Reputation: 402
I wish to cast an object into a generic delegate with system.type information so that I can invoke the delegate. 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);
does not compile for obvious reasons, however I fail to grasp the syntax required to do 2 things:
delegateObject
to CallbackFn<T>
InterfaceBase data
to InterfacedDataType<T>
Edit:
The invoke function has to be kept with the current signature:
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:
List<CallbackFnWraper> fnlist;
foreach(var fn in fnlist) fn.Invoke(somedata);
Edit 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();
}
}
Upvotes: 1
Views: 1389
Reputation: 136074
Actually this turned out to be pretty simple. You simply needed to cast your delegateObject
to a Delegate
type and call 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
Upvotes: 3