我希望将一个对象转换为带有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);
无法编译,但是我无法掌握执行两项操作所需的语法:
delegateObject
投放到CallbackFn<T>
InterfaceBase data
投放到InterfacedDataType<T>
修改:
调用函数必须与当前签名保持一致:
public void Invoke(InterfaceBase data)
此功能用于没有可用类型信息的范围,因此我无法模板化该功能。
示例使用invoke的函数:
List<CallbackFnWraper> fnlist;
foreach(var fn in fnlist) fn.Invoke(somedata);
编辑2:
我制作了一个小程序,即“最小,完整,可验证的”#34;所以如果有人想试一试:
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();
}
}
答案 0 :(得分:2)
实际上事实证明这很简单。您只需将delegateObject
转换为Delegate
类型并致电DynamicInvoke
。
public struct Wrapper
{
public System.Type T;
public object delegateObject;
public void Invoke(DataTypeBase data)
{
((Delegate)delegateObject).DynamicInvoke(data); //Will compile
}
}