This works (in C# 4.0 at least - not tried in earlier versions):
SomeDelegate a = Inc;
Func<int, int> c = new Func<int, int>(a);
If you look at the IL, this compiles into exactly the same code as Winston's answer. Here's the IL for the second line of what I just wrote:
ldloc.0
ldftn instance int32 ConsoleApplication1.Program/SomeDelegate::Invoke(int32)
newobj instance void class [mscorlib]System.Func`2<int32,int32>::.ctor(object, native int)
And that's also precisely what you see if you assign a.Invoke
into c
.
Incidentally, although Diego's solution is more efficient, in that the resulting delegate refers directly to the underlying method rather than going through the other delegate, it doesn't handle multicast delegates correctly. Winston's solution does, because it just defers completely to the other delegate. If you want a direct solution that also handles delegates with multiple targets, you need something a little more complex:
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;
}
This does the right thing for delegates with a single target by the way—it will end up producing just a single delegate of the target type that refers directly to whatever method (and where applicable, object) the input delegate referred to.