web-dev-qa-db-fra.com

Existe-t-il une fonction générique Parse () qui convertira une chaîne en un type quelconque à l'aide de l'analyse?

Je souhaite convertir une chaîne en un type générique tel que int ou date ou long en fonction du type de retour générique.

Fondamentalement, une fonction telle que Parse<T>(String) qui renvoie un élément de type T

Par exemple, si un int est passé, la fonction doit faire int.parse en interne.

70
Karim

System.Convert.ChangeType

Selon votre exemple, vous pourriez faire:

int i = (int)Convert.ChangeType("123", typeof(int));
DateTime dt = (DateTime)Convert.ChangeType("2009/12/12", typeof(DateTime));

Pour satisfaire à votre exigence de "type de retour générique", vous pouvez écrire votre propre méthode d'extension:

public static T ChangeType<T>(this object obj)
{
    return (T)Convert.ChangeType(obj, typeof(T));
}

Cela vous permettra de faire:

int i = "123".ChangeType<int>();
102
Ani

On dirait bien que je suis trop tard pour répondre à ce sujet. Mais voici ma mise en œuvre:

En gros, j'ai créé une méthode Extention pour la classe Object. Il gère tous les types, à savoir nullable, classes et struct.

 public static T ConvertTo<T>(this object value)
           {
               T returnValue;

               if (value is T variable)
                   returnValue = variable;
               else
                   try
                   {
                       //Handling Nullable types i.e, int?, double?, bool? .. etc
                       if (Nullable.GetUnderlyingType(typeof(T)) != null)
                       {
                           TypeConverter conv = TypeDescriptor.GetConverter(typeof(T));
                           returnValue = (T) conv.ConvertFrom(value);
                       }
                       else
                       {
                           returnValue = (T) Convert.ChangeType(value, typeof(T));
                       }
                   }
                   catch (Exception)
                   {
                       returnValue = default(T);
                   }

               return returnValue;
           }
13
Pranay Deep

System.Convert.ChangeType ne convertit en aucun type. Pensez à ce qui suit:

  • types nullables
  • enums
  • Guid etc.

Ces conversions sont possibles avec cette implémentation de ChangeType .

10
Alex Siepman

version plus propre de réponse de Pranay

public static T ConvertTo<T>(this object value)
{
    if (value is T variable) return variable;

    try
    {
        //Handling Nullable types i.e, int?, double?, bool? .. etc
        if (Nullable.GetUnderlyingType(typeof(T)) != null)
        {
            return (T)TypeDescriptor.GetConverter(typeof(T)).ConvertFrom(value);
        }

        return (T)Convert.ChangeType(value, typeof(T));
    }
    catch (Exception)
    {
        return default(T);
    }
}
5
Eonasdan

Il existe plusieurs conventions dans le .NET pour convertir des objets d’un type à un autre.

Mais ces méthodes sont beaucoup plus lentes que votre T.Parse(string) typique, provoquent la boxe et impliquent de nombreuses allocations à chaque fois que vous souhaitez convertir une seule valeur.

Pour ValueString , j'ai choisi de rechercher une méthode d'analyse statique appropriée du type en utilisant la réflexion, de construire une expression lambda pour l'appeler et de mettre en cache le délégué compilé pour une utilisation ultérieure (voir cette réponse pour un exemple).

Cela renvoie également aux méthodes que j'ai mentionnées ci-dessus si le type ne dispose pas d'une méthode d'analyse appropriée (voir la section performance dans le fichier Lisez-moi).

var v = new ValueString("15"); // struct
var i = v.As<int>(); // Calls int.Parse.
0
Şafak Gür