簡體   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