40 votes

comment obtenir la valeur par défaut d'un type si le type est uniquement connu sous le nom System.Type?

Si je veux une méthode qui renvoie la valeur par défaut d'un type donné et que la méthode est générique, je peux retourner une valeur par défaut comme ceci:

 public static T GetDefaultValue()
{
  return default(T);
}
 

Puis-je faire quelque chose de similaire si j'ai le type uniquement en tant qu'objet System.Type ?

 public static object GetDefaultValue(Type type)
{
  //???
}
 

69voto

Mark Brackett Points 46824

Comme vous n'avez vraiment à vous soucier que des types de valeur (les types de référence seront simplement nuls), vous pouvez utiliser Activator.CreateInstance pour appeler le constructeur par défaut sur eux.

 public static object GetDefaultValue(Type type) {
   return type.IsValueType ? Activator.CreateInstance(type) : null;
}
 

Edit: Jon a (bien sûr) raison. IsClass n'est pas assez exhaustif - il renvoie False si type est une interface.

7voto

jonfuller Points 265

Voici comment je le fais normalement. Cela évite tout le «IsValueType» ou la recherche de problèmes de constructeurs.

 public static object MakeDefault(this Type type)
{
    var makeDefault = typeof(ExtReflection).GetMethod("MakeDefaultGeneric");
    var typed = makeDefault.MakeGenericMethod(type);
    return typed.Invoke(null, new object[] { });
}

public static T MakeDefaultGeneric<T>()
{
    return default(T);
}
 

5voto

nawfal Points 13500

Même effet que la réponse de Mark, mais vérifie au préalable la nullité des structures nullables:

 public static object GetDefaultValue(this Type t)
{
    if (!t.IsValueType || Nullable.GetUnderlyingType(t) != null)
        return null;

    return Activator.CreateInstance(t);
}
 

1voto

harpo Points 17399

Sans générique, vous ne pouvez pas garantir que le type possède un constructeur sans paramètre, mais vous pouvez en rechercher un à l'aide de la réflexion:

 public static object GetDefaultValue(Type type)
{
    ConstructorInfo ci = type.GetConstructor( new Type[] {} );
    return ci.Invoke( new object[] {} );
}
 

J'ai essayé cela dans une application console, et elle renvoie une instance "par défaut" de la classe - en supposant que c'est une classe. Si vous en avez besoin pour fonctionner également pour les types de référence, vous aurez besoin d'une technique supplémentaire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X