71 votes

Le moyen le plus efficace d'obtenir le constructeur par défaut d'un type

Quel est le moyen le plus efficace d’obtenir le constructeur par défaut (c’est-à-dire un constructeur d’instance sans paramètre) d’un System.Type?

Je pensais quelque chose dans le sens du code ci-dessous, mais il semble qu'il devrait y avoir un moyen plus simple et plus efficace de le faire.

 Type type = typeof(FooBar)
BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
type.GetConstructors(flags)
    .Where(constructor => constructor.GetParameters().Length == 0)
    .First();
 

130voto

Curt Hagenlocher Points 12432
type.GetConstructor(Type.EmptyTypes)

29voto

Alex Lyman Points 7480

Si vous avez réellement besoin de la ConstructorInfo objet, puis de voir Curt Hagenlocher de réponse.

D'autre part, si vous êtes vraiment juste essayer de créer un objet au moment de l'exécution à partir d'un System.Type, voir System.Activator.CreateInstance -- ce n'est pas seulement paré pour l'avenir (Activateur gère plus de détails que ConstructorInfo.Invoke), il est aussi beaucoup moins moche.

2voto

DaFlame Points 51

Si vous avez le paramètre de type générique, puis Jeff Bridgman la réponse est la meilleure. Si vous avez seulement un objet de Type représente le type que vous voulez construire, vous pouvez utiliser Activator.CreateInstance(Type) comme Alex Lyman suggéré, mais on m'a dit qu'il est lent (je n'ai pas profilé personnellement).

Toutefois, si vous trouvez vous-même la construction de ces objets, très souvent, il est plus éloquent, à l'aide compilé dynamiquement les Expressions Linq:

using System;
using System.Linq.Expressions;

public static class TypeHelper
{
    public static Func<object> CreateDefaultConstructor(Type type)
    {
        NewExpression newExp = Expression.New(type);

        // Create a new lambda expression with the NewExpression as the body.
        var lambda = Expression.Lambda<Func<object>>(newExp);

        // Compile our new lambda expression.
        return lambda.Compile();
    }
}

Il suffit d'appeler le délégué est retourné à vous. Vous devriez cache ce délégué, car constamment en recompilant les expressions Linq peuvent être coûteux, mais si vous cache le délégué et le réutiliser à chaque fois, il peut être très rapide! Personnellement, j'utilise un statique de recherche dictionnaire indexé par type. Cette fonction est pratique lorsque vous traitez avec des objets sérialisés où vous ne pouvez connaître le Type de l'information.

NOTE: Cette opération peut échouer si le type n'est pas constructable ou ne possède pas de constructeur par défaut!

0voto

Jeff Bridgman Points 2545

Si vous souhaitez uniquement que le constructeur par défaut instancie la classe et obtenez le type en tant que paramètre de type générique pour une fonction, vous pouvez procéder comme suit:

 T NewItUp<T>() where T : new()
{
   return new T();
}
 

-2voto

Mohamed Faramawi Points 322

vous voulez essayer FormatterServices.GetUninitializedObject(Type) c'est mieux que de l'Activateur.CreateInstance

Cependant , cette méthode n'appelle pas le constructeur de l'objet , donc, si vous définissez des valeurs initiales il y a, cela ne fonctionne pas Vérifier MSDN pour cette chose http://msdn.microsoft.com/en-us/library/system.runtime.serialization.formatterservices.getuninitializedobject.aspx

il est une autre façon ici http://www.ozcandegirmenci.com/post/2008/02/Create-object-instances-Faster-than-Reflection.aspx

mais celui-ci échoue si l'objet ont paramétrer les constructeurs

Espérons que cette aide

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