Cela fonctionne (en C# 4.0 au moins - pas essayé dans les versions antérieures):
SomeDelegate a = Inc;
Func<int, int> c = new Func<int, int>(a);
Si vous regardez l'IL, cette compile dans exactement le même code que la réponse de Winston. Voici l'IL pour la deuxième ligne de ce que je viens d'écrire:
ldloc.0
ldftn instance int32 ConsoleApplication1.Program/SomeDelegate::Invoke(int32)
newobj instance void class [mscorlib]System.Func`2<int32,int32>::.ctor(object, native int)
Et c'est aussi précisément ce que vous voyez si vous attribuez a.Invoke
en c
. Incidemment, bien que la solution de Diego soit plus efficace, en ce sens que le délégué résultant se réfère directement à la méthode sous-jacente plutôt que de passer par l'autre délégué, il ne gère pas correctement les délégués de multidiffusion. La solution de Winston, parce qu'elle se contente de renvoyer complètement à l'autre délégué. Si vous voulez une solution directe qui gère également les délégués avec des cibles multiples, vous avez besoin quelque chose d'un peu plus complexe:
public static TResult DuplicateDelegateAs<TResult>(MulticastDelegate source)
{
Delegate result = null;
foreach (Delegate sourceItem in source.GetInvocationList())
{
var copy = Delegate.CreateDelegate(
typeof(TResult), sourceItem.Target, sourceItem.Method);
result = Delegate.Combine(result, copy);
}
return (TResult) (object) result;
}
Cela fait la bonne chose pour les délégués avec une seule cible par la façon dont-il finira par produire seulement un délégué unique du type cible qui fait directement référence à la méthode (et, le cas échéant, à l'objet) référencée par le délégué d'entrée.
Peut-être souligner le fait que les trucs personnalisés que vous avez écrit est normalement fait par la magie du compilateur. – Dykam
+1 pour la bonne explication. Il y a un moyen plus simple que * Func c = x => a (x); * cependant - voir ma réponse. –
Je présume que dans le dernier bit 'public Foo' aurait dû être' public MyLambda'? – Chris