简体   繁体   English

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

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

I wish to cast an object into a generic delegate with system.type information so that I can invoke the delegate. 我希望将一个对象转换为具有system.type信息的通用委托,以便我可以调用该委托。 The object is guaranteed to be convertible to the delegate. 该对象保证可以转换为委托。

Delegate example: 委托示例:

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

And the struct holding the callback object and type information: 以及包含回调对象和类型信息的结构:

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

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

The line ((CallbackFn<T>)(delegateObject)).Invoke((T)data); ((CallbackFn<T>)(delegateObject)).Invoke((T)data); does not compile for obvious reasons, however I fail to grasp the syntax required to do 2 things: 不会出于明显的原因进行编译,但是我无法掌握执行两件事所需的语法:

  1. Cast delegateObject to CallbackFn<T> delegateObjectCallbackFn<T>
  2. Cast InterfaceBase data to InterfacedDataType<T> InterfaceBase dataInterfacedDataType<T>

Edit : 编辑

The invoke function has to be kept with the current signature: invoke函数必须与当前签名保持在一起:

public void Invoke(InterfaceBase data) 

This function is used in a scope where there is no type information available so I cant template that function. 在没有可用类型信息的范围内使用此函数,因此我无法对该函数进行模板化。

Example Function where invoke is used: 使用invoke的示例函数:

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

Edit 2: 编辑2:

I made a small program that is "Minimal, Complete, and Verifiable" so if anyone wants to give it a shot: 我制作了一个“最小,完整和可验证”的小程序,因此,如果有人想试一试:

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();
    }
}

Actually this turned out to be pretty simple. 实际上,事实证明这很简单。 You simply needed to cast your delegateObject to a Delegate type and call DynamicInvoke . 您只需要将您的delegateObject转换为Delegate类型并调用DynamicInvoke

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

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

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

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

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