Dies funktioniert (in C# 4.0 zumindest - in früheren Versionen nicht versucht):
SomeDelegate a = Inc;
Func<int, int> c = new Func<int, int>(a);
Wenn man sich die IL suchen, diese kompiliert in genau den gleichen Code wie Winston Antwort. Hier ist die IL für die zweite Zeile von dem, was ich gerade geschrieben habe:
ldloc.0
ldftn instance int32 ConsoleApplication1.Program/SomeDelegate::Invoke(int32)
newobj instance void class [mscorlib]System.Func`2<int32,int32>::.ctor(object, native int)
Und das ist auch genau das, was Sie sehen, wenn Sie a.Invoke
in c
zuweisen.
Übrigens, obwohl Diegos Lösung effizienter ist, da der resultierende Delegat direkt auf die zugrunde liegende Methode verweist und nicht durch den anderen Delegaten geht, behandelt er Multicastdelegaten nicht korrekt. Winstons Lösung tut das, weil sie sich nur komplett auf den anderen Delegierten verlagert. Wenn Sie eine direkte Lösung wollen, die auch Teilnehmer mit mehreren Zielen behandelt, müssen Sie etwas ein wenig komplexe:
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;
}
Dies ist das Richtige für die Teilnehmer mit einem einzigen Ziel durch die Art und Weise-es produziert wird am Ende nur ein einzelner Delegat des Zieltyps, der direkt auf die Methode (und ggf. das Objekt) verweist, auf die sich der betreffende Eingabe-Delegat bezieht.
Vielleicht betonen Sie die Tatsache, dass die benutzerdefinierten Sachen, die Sie geschrieben haben, normalerweise durch Compiler-Magie erledigt werden. – Dykam
+1 für die nette Erklärung. Es gibt einen einfacheren Weg als * Func c = x => a (x); * obwohl - siehe meine Antwort. –
Ich nehme an, im letzten Bit hätte 'public Foo'' public MyLambda' sein sollen? – Chris