web-dev-qa-db-fra.com

Comment rendre le type de retour d'une méthode générique?

Existe-t-il un moyen de rendre cette méthode générique afin que je puisse renvoyer une chaîne, bool, int ou double? À l'heure actuelle, il renvoie une chaîne, mais s'il est capable de trouver "true" ou "false" comme valeur de configuration, j'aimerais renvoyer une valeur bool, par exemple.

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

Vous devez en faire une méthode générique, comme ceci:

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

Mais l'appelant devra spécifier le type qu'ils attendent. Vous pouvez ensuite utiliser potentiellement Convert.ChangeType , en supposant que tous les types pertinents sont pris en charge:

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

Je ne suis pas entièrement convaincu que tout cela soit une bonne idée, remarquez ...

308
Jon Skeet

Vous pouvez utiliser Convert.ChangeType():

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

Il y a plusieurs façons de le faire (énumérées par priorité, en fonction du problème du PO)

  1. Option 1: approche directe - Créez plusieurs fonctions pour chaque type attendu plutôt que d'avoir une fonction générique.

    public static bool ConfigSettingInt(string settingName)
    {  
         return Convert.ToBoolean(ConfigurationManager.AppSettings[settingName]);
    }
    
  2. Option 2: lorsque vous ne souhaitez pas utiliser de méthodes de conversion sophistiquées - Convertissez la valeur en objet puis en type générique.

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

    Note - Cela provoquera une erreur si le casting n'est pas valide (votre cas). Je ne recommanderais pas cela si vous n’êtes pas sûr de la conversion de caractères, choisissez plutôt l’option 3.

  3. Option 3: Générique avec type de sécurité - Créer une fonction générique pour gérer la conversion de type.

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

    Note - T est le type attendu, notez ici la contrainte where (le type de U doit être convertible pour nous éviter les erreurs)

8
RollerCosta

Vous devez convertir le type de votre valeur de retour de la méthode en type générique que vous transmettez à la méthode lors de l'appel.

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

Vous devez passer un type castable pour la valeur renvoyée par cette méthode.

Si vous souhaitez renvoyer une valeur qui n'est pas transtypable au type générique que vous transmettez, vous devrez peut-être modifier le code ou vous assurer de transmettre un type transtablissable pour la valeur de retour de method. Donc, cette approche n'est pas recommandée.

6
Vinay Chanumolu

Veuillez essayer le code ci-dessous:

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

Créez une fonction et transmettez le paramètre put en tant que type générique.

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