当前位置: 首页 > 编程语言 > C#

C#中如何通过类型创建动态委托对象?分享

时间:2023-04-11 11:52:42 C#

C#中如何按类型创建动态委托对象?假设我有一个我知道派生自委托类型的类型。我想创建一个这种类型的对象,它包装一个接受任意参数并返回正确返回类型的对象的匿名委托:varretType=type.GetMethod("Invoke").ReturnType;varobj=Delegate.CreateDelegate(type,delegate(object[]args){...if(retType!=typeof(void))...以某种方式创建retType类型的对象并返回它...});显然这不会编译,因为CreateDelegate需要MethodInfo作为第二个参数。我应该怎么做才能正确?更新:有关我要实现的目标的更多信息。有两个应用程序在运行——浏览器中的客户端和C#中的服务器。浏览器能够通过将参数序列化为JSON并通过网络发送调用(如RPC)来调用服务器端的远程函数。这已经有效,但我想添加对回调的支持。例如:JavaScript(客户端):functiononNewObject(uuid){console.log(uuid);}server.notifyAboutNewObjects(onNewObject);C#(服务器):voidnotifyAboutNewObjects(Actioncallback){...callback("new-object-uuid");...}中间件代码将接收来自浏览器的调用,并且需要生成一个假的回调委托,该委托实际上将调用回调发送回浏览器并阻塞线程直到它完成。用于发送/接收的代码已经存在,我只是停留在如何生成一个通用委托上,该委托将简单地将所有参数放入一个数组并将它们传递给发送代码。更新:如果有人可以编写将在运行时生成此类委托的代码(例如使用DynamicMethod),我会认为这是一个有效的答案。我只是没有足够的时间来学习如何做到这一点,希望有经验的人能够足够快地编写这段代码。本质上,代码应该只接受任意委托参数(运行时可用的列表和类型),将它们放入一个数组中并调用泛型方法。泛型方法总是会返回一个对象,应该将其转换为相应的返回类型,或者如果函数返回void则忽略。更新:我已经创建了一个小型测试程序来显示我需要的东西:usingSystem;使用System.Reflection;namespaceTestDynamicDelegates{classMainClass{//测试函数,我们需要为其创建默认参数。私有静态字符串Foobar(floatx,Actiona1,Funca2){a1(42);返回a2("测试");}//代表泛型函数的委托。私有委托对象AnyFunc(paramsobject[]args);//构造一组要传递给函数的默认参数。privatestaticobject[]ConstructParams(ParameterInfo[]paramInfos){object[]methodParams=newobject[paramInfos.Length];for(vari=0;i)Foobar;ParameterInfo[]paramInfo=d.Method.GetParameters();object[]methodParams=ConstructParams(paramInfo);Console.WriteLine("{0}返回:{1}",d.Method.Name,d.DynamicInvoke(methodParams));}}我编写了一个名为Dynamitey(在nuget中)的开源PCL库,它使用C#DLR来执行各种动态操作。它特别有一个名为Dynamic.CoerceToDelegate(objectinvokeableObject,TypedelegateType)Dynamic.CoerceToDelegate(objectinvokeableObject,TypedelegateType)的静态方法,它基本上使用CompiledExpressions(源)来包含DynamicObject或更一般的委托的动态调用,具有特定的委托类型.使用System.Dynamic,您可以创建一个可调用对象:publicclassAnyInvokeObject:DynamicObject{Func_func;publicAnyInvokeObject(Funcfunc){_func=func;}publicoverrideboolTryInvoke(InvokeBinderbinder,object[]args,outobjectresult){result=_func(args);返回真;然后在你的示例中:vartmpObj=newAnyInvokeObject(args=>{Console.WriteLine("Invokeddynamicdelegatewithfollowingparameters:");for(varHowaboutasolutionwherej=0;jhasnodelegate?(警告:猖獗的伪代码)classAbstractServerToClientMessage{publicvirtualstringToJSON();}classOnNewObjectMessage:AbstractServerToClientMessage{...}classOnSomethingElseHappenedMessage:AbstractServerToClientMessage{...}voidNotifyClient(AbstractServerToClientMessagemessage)eventOnNewObject;eventOnSomethingElseHappened;voidnotifyAboutNewObjects(){...OnNewObject+=NotifyClient;...}voidAddNewObject(SomeObjectobj){OnNewObjectMessagemessage(obj);OnNewObject(message);//实际添加对象}无论如何都会传递消息连载,何必呢?多态性会处理剩下的事情。唯一的要求是有一组消息对应于每个事件类型。返回值可以通过写入AbstractServerToClientMessage的字段来实现。或者您实际上可以有一个具有固定签名的委托,它接受类似AbstractServerToClientMessage的东西。多态性(+反序列化类工厂)也将允许将其转换为正确的消息类型。可以看看SignalR的源码,也可以直接使用。在浏览器中注册一个服务端可以调用的函数varconnection=$.hubConnection();varyourHubProxy=connection.createHubProxy('yourHub');yourHubProxy.on('addMessageToConsole',function(message){console.log(message);});在服务器上publicclassYourHub:Hub{publicvoidSendMessage(stringmessage){Clients.All.addMessageToConsole(message);有关更多示例,请参见此处在C#中按类型创建动态委托对象?如果分享的所有内容对您有用,需要了解更多C#学习教程,希望您多多关注---本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:

最新推荐
猜你喜欢