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 Store Apps, but my code does not compile. The compiler says that it cannot find the method on the Delegate
type.
The funny thing is that e.g. the PRISM library by Microsoft can call 'Delegate.CreateDelegate' from a Portable Class Library. It does so in the DelegateReference
class. The PRISM portable class library targets .NET 4.0, Windows 8 Store Apps, Windows Phone 8 and Silverlight 5 (and thusly an even more restrictive set).
The code that does not compile looks like this:
public class MyClass
{
public void MyMethod<T>(EventHandler handler)
{
var @delegate = Delegate.CreateDelegate(typeof (OpenEventHandler<T>), null, handler.GetMethodInfo());
}
}
public delegate void OpenEventHandler<in T>(T target, object sender, EventArgs arguments);
An example can be downloaded here: https://dl.dropboxusercontent.com/u/14810011/PortableClassLibraryReferenceProblem.zip
It contains my library project and a very stripped version of the PRISM PubSubEvents project containing only the DelegateReference
class and its interface. The complete source code of the latter can be found here: http://prismwindowsruntime.codeplex.com/SourceControl/latest
What can I do to use all Delegate
members? Thank you in advance for your help!
EDIT after Henk Holterman's answer:
GetMethodInfo() is an extension method that is supported by the PCL subset. Anyway, that is not related to the problem that I cannot call Delegate.CreateDelegate
while PRISM's PCL project can.
EDIT 2 after Hans Passants comment:
I just played around and found out that when I activate Silverlight 5 as a target of the portable library then Delegate.CreateDelegate
is indeed accessible (and the GetMethodInfo Extension Method no longer is). Is Delegate.CreateDelegate
then maybe mapped to another API for Windows 8 Store and Phone apps internally? It's the only way I could think of how this method would be suddenly accessible just because I added Silverlight 5 as a valid target.
(You can reproduce this by right-clicking on the "MyPortableClassLibrary" project, click "Properties" and in the "Library" tab click change to select the frameworks that are targeted by the portable library.)
Also, earlier today, I created an Windows Store App project and saw that there was no CreateDelegate
method defined on the Delegate
class in .NET for Windows Runtime.
In my actual project, I do not want to target Silverlight 5 as I use IObservable<T>
and IObserver<T>
heavily using Rx and these interfaces are not defined in Silverlight.
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With