it-swarm.com.de

Wie mache ich den Rückgabetyp einer Methode generisch?

Gibt es eine Möglichkeit, diese Methode generisch zu machen, damit ich einen String, ein Bool, ein Int oder ein Double zurückgeben kann? Momentan wird ein String zurückgegeben, aber wenn der Konfigurationswert "true" oder "false" lautet, möchte ich beispielsweise einen Bool zurückgeben.

    public static string ConfigSetting(string settingName)
    {  
         return ConfigurationManager.AppSettings[settingName];
    }
143
MacGyver

Sie müssen es zu einer generischen Methode machen, wie folgt:

public static T ConfigSetting<T>(string settingName)
{  
    return /* code to convert the setting to T... */
}

Der Aufrufer muss jedoch den Typ angeben, den er erwartet. Sie könnten dann möglicherweise Convert.ChangeType unter der Annahme, dass alle relevanten Typen unterstützt werden:

public static T ConfigSetting<T>(string settingName)
{  
    object value = ConfigurationManager.AppSettings[settingName];
    return (T) Convert.ChangeType(value, typeof(T));
}

Ich bin nicht ganz davon überzeugt, dass dies alles eine gute Idee ist, wohlgemerkt ...

308
Jon Skeet

Sie könnten Convert.ChangeType() verwenden:

public static T ConfigSetting<T>(string settingName)
{
    return (T)Convert.ChangeType(ConfigurationManager.AppSettings[settingName], typeof(T));
}
25
BrokenGlass

Es gibt viele Möglichkeiten, dies zu tun (nach Priorität aufgelistet, spezifisch für das OP-Problem)

  1. Option 1: Gerader Ansatz - Erstellen Sie mehrere Funktionen für jeden Typ, den Sie erwarten, anstatt eine generische Funktion zu haben.

    public static bool ConfigSettingInt(string settingName)
    {  
         return Convert.ToBoolean(ConfigurationManager.AppSettings[settingName]);
    }
    
  2. Option 2: Wenn Sie keine ausgefallenen Konvertierungsmethoden verwenden möchten - Konvertieren Sie den Wert in object und dann in generic type.

    public static T ConfigSetting<T>(string settingName)
    {  
         return (T)(object)ConfigurationManager.AppSettings[settingName];
    }
    

    Hinweis - Dies wird einen Fehler auslösen, wenn die Besetzung nicht gültig ist (Ihr Fall). Ich würde nicht empfehlen, dies zu tun, wenn Sie sich nicht sicher sind, was das Typ-Casting angeht, sondern gehen Sie zu Option 3.

  3. Option 3: Generisch mit Typensicherheit - Erstellen Sie eine generische Funktion für die Typenkonvertierung.

    public static T ConvertValue<T,U>(U value) where U : IConvertible
    {
        return (T)Convert.ChangeType(value, typeof(T));
    } 
    

    Hinweis - T ist der erwartete Typ, beachten Sie die Where-Bedingung hier (Typ von U muss IConvertible sein, um uns vor den Fehlern zu schützen)

8
RollerCosta

Sie müssen den Typ Ihres Rückgabewerts der Methode in den generischen Typ konvertieren, den Sie beim Aufruf an die Methode übergeben.

    public static T values<T>()
    {
        Random random = new Random();
        int number = random.Next(1, 4);
        return (T)Convert.ChangeType(number, typeof(T));
    }

Sie müssen einen Typ übergeben, der für den Wert, den Sie über diese Methode zurückgeben, umwandelbar ist.

Wenn Sie einen Wert zurückgeben möchten, der nicht in den übergebenen generischen Typ umwandelbar ist, müssen Sie möglicherweise den Code ändern oder sicherstellen, dass Sie einen Typ übergeben, der für den Rückgabewert von method umwandelbar ist. Dieser Ansatz wird also nicht empfohlen.

6
Vinay Chanumolu

Bitte versuchen Sie es mit folgendem Code:

public T? GetParsedOrDefaultValue<T>(string valueToParse) where T : struct, IComparable
{
 if(string.EmptyOrNull(valueToParse))return null;
  try
  {
     // return parsed value
     return (T) Convert.ChangeType(valueToParse, typeof(T));
  }
  catch(Exception)
  {
   //default as null value
   return null;
  }
 return null;
}
0
Sid

Erstellen Sie eine Funktion und übergeben Sie den Parameter put als generischen Typ.

 public static T some_function<T>(T out_put_object /*declare as Output object*/)
    {
        return out_put_object;
    }
0
Prabhakar