I have the following problem: I want to call Delegate.CreateDelegate
from within my Portable Class Library targeting .NET 4.5, Windows Phone 8 and Windows 8 Sto
What you are seeing when you add/remove Silverlight, is portable flipping between two different .NET API surface areas. I cover these two different surface areas here: What is .NET Portable Subset (Legacy)?.
In what we call the legacy surface area, this method lives on Delegate. In the new surface area, this method has been moved to MethodInfo.
Why did we do this?
For layering reasons. In the new surface, reflection types (ie Assembly, MemberInfo, MethodInfo, etc) are considered as living in a higher layer than the core primitives, which includes Delegate. Unlike the legacy surface area (where they all live in mscorlib), these types in different assemblies; System.Reflection.dll and System.Runtime.dll, respectively.
This method (a few others) were causing something at a lower layer (System.Runtime.dll) to depend on something at a higher layer (System.Reflection.dll). To prevent that, the dependency was reversed.
OK, after a night of sleeping I recognized that my question actually should be "How do I dynamically create delegates in the new API introduced with the Windows Runtime?". As Rafael indicated in the comments of my question, different APIs are provided when Windows 8 / Phone 8 is targeted in addition to .NET. If Silverlight is also targeted, then APIs that are not available in Windows 8 / Phone 8 will be mapped and this explains why I can suddenly call Delegate.CreateDelegate
when I add Silverlight as a target of the Portable Class Library. In .NET, the new APIs for Reflection were introduced with .NET 4.5.
Anyway, to create a delegate in Windows 8 / Windows Phone 8, one has to use the MethodInfo.CreateDelegate
method, just like this:
public class MyClass
{
public void MyMethod<T>(EventHandler handler)
{
var methodInfo = handler.GetMethodInfo();
var @delegate = methodInfo.CreateDelegate(typeof(OpenEventHandler<T>), null);
}
}
public delegate void OpenEventHandler<in T>(T target, object sender, EventArgs arguments);