繁体   English   中英

使用system.type将对象转换为通用委托

[英]Cast object to generic delegate using system.type

我希望将一个对象转换为具有system.type信息的通用委托,以便我可以调用该委托。 该对象保证可以转换为委托。

委托示例:

public delegate void CallbackFn<T>(InterfacedDataType<T> data) where T : InterfaceBase;

以及包含回调对象和类型信息的结构:

public struct CallbackFnWrapper
{
    public System.Type T;
    public object delegateObject;

    public void Invoke(InterfaceBase data) 
    {
        ((CallbackFn<T>)(delegateObject)).Invoke((T)data); //Does not compile
    }
}

((CallbackFn<T>)(delegateObject)).Invoke((T)data); 不会出于明显的原因进行编译,但是我无法掌握执行两件事所需的语法:

  1. delegateObjectCallbackFn<T>
  2. InterfaceBase dataInterfacedDataType<T>

编辑

invoke函数必须与当前签名保持在一起:

public void Invoke(InterfaceBase data) 

在没有可用类型信息的范围内使用此函数,因此我无法对该函数进行模板化。

使用invoke的示例函数:

List<CallbackFnWraper> fnlist;
foreach(var fn in fnlist) fn.Invoke(somedata);

编辑2:

我制作了一个“最小,完整和可验证”的小程序,因此,如果有人想试一试:

public class DataTypeBase { }

public class DataTypeDerivedA : DataTypeBase
{
    public int i = 0;
}

public class DataTypeDerivedB : DataTypeBase
{
    public char c = ' ';
}

public class RunEnvironment
{
    public void Run()
    {
        DataTypeDerivedA a = new DataTypeDerivedA();
        a.i = 555;
        DataTypeDerivedB b = new DataTypeDerivedB();
        b.c = '@';
        Wrapper w1 = MakeWrapper<DataTypeDerivedA>(Test1);
        Wrapper w2 = MakeWrapper<DataTypeDerivedB>(Test2);

        w1.Invoke(a);
        w2.Invoke(b);
    }

    public Wrapper MakeWrapper<T>(CallbackFn<T> fn) where T : DataTypeBase
    {
        Wrapper w = new Wrapper();
        w.T = typeof(T);
        w.delegateObject = fn;
        return w;
    }

    public void Test1(DataTypeDerivedA data)
    {
        System.Console.WriteLine(data.i);
    }

    public void Test2(DataTypeDerivedB data)
    {
        System.Console.WriteLine(data.c);
    }
}

public delegate void CallbackFn<T>(T data) where T : DataTypeBase;
public struct Wrapper
{
    public System.Type T;
    public object delegateObject;

    public void Invoke(DataTypeBase data)
    { 
        ((CallbackFn<T>)(delegateObject)).Invoke((T)(data)); //Won't compile
    }
}

public class Program
{
    public static void Main(string[] args)
    {
        RunEnvironment r = new RunEnvironment();
        r.Run();
    }
}

实际上,事实证明这很简单。 您只需要将您的delegateObject转换为Delegate类型并调用DynamicInvoke

public struct Wrapper
{
    public System.Type T;
    public object delegateObject;

    public void Invoke(DataTypeBase data)
    { 
       ((Delegate)delegateObject).DynamicInvoke(data); //Will compile
    }
}

工作示例: http : //rextester.com/CQG34502

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM