feO*_*O2x 10 c# portable-class-library
我有以下问题:我想Delegate.CreateDelegate从我的可移植类库中调用.NET 4.5,Windows Phone 8和Windows 8 Store Apps,但我的代码无法编译.编译器说它无法在Delegate类型上找到方法.
有趣的是,例如Microsoft的PRISM库可以从便携式类库中调用'Delegate.CreateDelegate'.它在DelegateReference课堂上这样做.PRISM便携式类库面向.NET 4.0,Windows 8商店应用程序,Windows Phone 8和Silverlight 5(因此是一个更具限制性的集合).
不编译的代码如下所示:
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);
Run Code Online (Sandbox Code Playgroud)
可以在此处下载示例:https://dl.dropboxusercontent.com/u/14810011/PortableClassLibraryReferenceProblem.zip
它包含我的库项目和PRISM PubSubEvents项目的非常剥离版本,该项目仅包含DelegateReference类及其接口.后者的完整源代码可以在这里找到:http://prismwindowsruntime.codeplex.com/SourceControl/latest
如何使用所有Delegate会员?预先感谢您的帮助!
在亨克霍尔特曼的答案之后编辑:
GetMethodInfo()是PCL子集支持的扩展方法.无论如何,这与我Delegate.CreateDelegate在PRISM的PCL项目中无法调用的问题无关.

在Hans Passants评论之后编辑2:
我只是玩了一遍,发现当我激活Silverlight 5作为可移植库的目标时,Delegate.CreateDelegate确实可以访问(并且GetMethodInfo扩展方法不再是).是Delegate.CreateDelegate那么也许映射到另一个API为Windows 8商店和Phone应用内部?这是我能想到如何突然访问这种方法的唯一方法,因为我添加了Silverlight 5作为有效目标.
(您可以通过右键单击"MyPortableClassLibrary"项目,单击"属性"并在"库"选项卡中单击更改以选择便携式库所针对的框架来重现此操作.)
此外,今天早些时候,我创建了一个Windows应用商店应用项目,并发现.NET for Windows Runtime中没有CreateDelegate为Delegate该类定义方法.
在我的实际项目中,我不想在使用IObservable<T>和IObserver<T>大量使用Rx时将Silverlight 5作为目标,并且这些接口未在Silverlight中定义.
feO*_*O2x 13
好吧,经过一夜的睡眠后,我发现我的问题实际应该是"如何在Windows运行时引入的新API中动态创建委托?" .正如Rafael在我的问题评论中指出的那样,除了.NET之外,当Windows 8/Phone 8被定位时,会提供不同的API.如果Silverlight也是目标,那么将映射Windows 8/Phone 8中不可用的API,这解释了Delegate.CreateDelegate当我将Silverlight添加为可移植类库的目标时,我可以突然调用的原因.在.NET中,使用.NET 4.5引入了用于Reflection的新API.
无论如何,要在Windows 8/Windows Phone 8中创建委托,必须使用该MethodInfo.CreateDelegate方法,如下所示:
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);
Run Code Online (Sandbox Code Playgroud)
Dav*_*ean 10
您在添加/删除Silverlight时看到的内容是可移植在两个不同的.NET API表面区域之间翻转.我在这里介绍了这两个不同的表面区域:什么是.NET Portable Subset(Legacy)?.
在我们称之为遗留表面区域的方法中,此方法位于Delegate上.在新的表面区域中,此方法已移至MethodInfo.
我们为什么这样做?
出于分层原因.在新的表面中,反射类型(即Assembly,MemberInfo,MethodInfo等)被认为生活在比核心基元更高的层中,其中包括Delegate.与传统的表面区域(它们都存在于mscorlib中)不同,这些类型在不同的组件中; System.Reflection.dll和System.Runtime.dll分别.
这个方法(其他一些)导致较低层(System.Runtime.dll)的某些东西依赖于更高层的东西(System.Reflection.dll).为了防止这种情况,依赖性被逆转了.
| 归档时间: |
|
| 查看次数: |
3959 次 |
| 最近记录: |