如何在运行时动态创建Action ?
我希望能够在运行时执行以下等效操作:
var action = new Action(obj => Console.WriteLine("Called = " + obj));
我知道我需要为Action获取正确的类型,但不知道如何使用Delegate.Create获取最后一位。 在Action定义中Type
表示T.
var actionType = typeof(Action).MakeGenericType(Type); var constructor = actionType.GetConstructors()[0]; var @delegate = Delegate.CreateDelegate(actionType, );
人们似乎缺少的一点是我正在尝试创建一个Action实例,其中T不能静态指定,因为它是从一个派生自Attribute的类中使用的 – 这意味着T可以是任何东西而且它不能被定义为通用定义
干杯
如果您知道您需要执行的操作是什么以及如何执行它而不管类型(如您的示例中)为什么不只是创建一个执行操作的通用方法并以这种方式创建您的委托?
class Program { public static void Perform(T value) { Console.WriteLine("Called = " + value); } public static Delegate CreateAction(Type type) { var methodInfo = typeof (Program).GetMethod("Perform").MakeGenericMethod(type); var actionT = typeof (Action<>).MakeGenericType(type); return Delegate.CreateDelegate(actionT, methodInfo); } static void Main(string[] args) { CreateAction(typeof (int)).DynamicInvoke(5); Console.ReadLine(); } }
您可以使用以下代码,如果类型可以转换为对象,它可以工作:
Action
但是,如果type是enum或其他值类型,则它将不起作用。
简短的回答是创建一个委托MyActionDelegate
,然后使用:
delegate void MyActionDelegate(T arg); Delegate @delegate = new MyActionDelegate((a) => Console.WriteLine(a));
这是一个使用generics类的工作示例:
public class MyClass { public delegate void ActionDelegate(T arg); public void RunGenericAction(T arg) { var actionType = typeof(Action<>).MakeGenericType(typeof(T)); var constructor = actionType.GetConstructors()[0]; Delegate @delegate = new ActionDelegate((a) => { Console.WriteLine(arg); }); var inst = (Action )constructor.Invoke(new object[] { @delegate.Target, @delegate.Method.MethodHandle.GetFunctionPointer() }); inst(arg); } }
像这样使用它,它输出123
到控制台:
var c = new MyClass(); c.RunGenericAction(123);
您会注意到我将两个参数传递给Constructor.Invoke
; 这是因为事实certificate,委托参数实际上编译为两个参数:函数的目标对象和指向函数的指针。 我不能因为那里花哨的步法而受到赞扬; 从这个关于如何使用reflection传递委托参数的优秀答案中 “借用”信息。
使用以下代码创建委托,该委托在type参数中后期绑定。 另请参见如何:使用reflection检查和实例化通用类型 。
abstract class ActionHelper { protected abstract Delegate CreateActionImpl(); // A subclass with a static type parameter private class ActionHelper : ActionHelper { protected override Delegate CreateActionImpl() { // create an Action and downcast return new Action (obj => Console.WriteLine("Called = " + (object)obj)); } } public static Delegate CreateAction(Type type) { // create the type-specific type of the helper var helperType = typeof(ActionHelper<>).MakeGenericType(type); // create an instance of the helper // and upcast to base class var helper = (ActionHelper)Activator.CreateInstance(helperType); // call base method return helper.CreateActionImpl(); } } // Usage // Note: The "var" is always "Delegate" var @delegate = ActionHelper.CreateAction(anyTypeAtRuntime);
也就是说,我不建议使用这种方法。 相反,使用
Action
它提供
上述就是C#学习教程:如何在运行时动态创建Action ?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/997985.html