Vous pouvez éviter d'utiliser DynamicInvoke
qui est douloureusement lent. Vous pouvez utiliser l'inférence de type en C# pour obtenir une instanciation générique de votre type anonyme. Quelque chose comme:
public static Func<object[], T> AnonymousInstantiator<T>(T example)
{
var ctor = typeof(T).GetConstructors().First();
var paramExpr = Expression.Parameter(typeof(object[]));
return Expression.Lambda<Func<object[], T>>
(
Expression.New
(
ctor,
ctor.GetParameters().Select
(
(x, i) => Expression.Convert
(
Expression.ArrayIndex(paramExpr, Expression.Constant(i)),
x.ParameterType
)
)
), paramExpr).Compile();
}
Maintenant, vous pouvez appeler,
var instantiator = AnonymousInstantiator(new { Name = default(string), Num = default(int) });
var a1 = instantiator(new object[] { "abc", 123 }); // strongly typed
var a2 = instantiator(new object[] { "xyz", 789 }); // strongly typed
// etc.
Vous pouvez utiliser la méthode AnonymousInstantiator
pour générer des fonctions pour instancier tout type anonyme avec un certain nombre de propriétés, juste que vous devez passer un approprié exemple en premier. Les paramètres d'entrée doivent être transmis en tant que tableau d'objets. Si vous vous inquiétez des performances de boxe, alors vous devez écrire un instantiateur personnalisé qui accepte seulement string
et int
comme paramètres d'entrée, mais l'utilisation d'un tel instanciant sera un peu plus limitée.
Dup possible de: http://stackoverflow.com/questions/606104/linq-expression-tree-question –
@Flash, ce n'est pas possible, du moins pas directement. Le compilateur fait beaucoup de "magie" lorsque vous créez des types anonymes - c'est du sucre syntaxique pour déclarer une véritable classe C# avec un tas de propriétés. Le compilateur fait tout cela pour vous. Il n'y a pas de type d'arbre d'expression qui fait tout cela automatiquement pour vous. Si vous regardez le lien que j'ai référencé, il fournit une solution de contournement. Cependant, il utilise Reflection.Emit, ce qui n'est pas pour la feinte du coeur. –
Kirk: L'OP veut * construire * une classe anonyme, pas * créer * une à partir de zéro. Tant qu'il sait au moment de la compilation quels sont les noms et les types des propriétés, il peut demander au compilateur de créer le type pour lui et tout ce qu'il a à faire est de savoir comment l'utiliser. – Gabe