问题
Why does the following Delegate.CreateDelegate produce a runtime ArgumentException?
static class Module1
{
public static void Main()
{
MyDataObject mdo = new MyDataObject();
mdo.DoMagic("Hello");
}
#region Assembly A
public class BusinessObject
{
}
public class MyBusinessObject : BusinessObject
{
public void DoMagic(string s)
{
Console.WriteLine(s);
}
}
#endregion
#region Assembly B
public class MyDataObject
{
private delegate void DoMagicDel(BusinessObject bo, string s);
private DoMagicDel delDoMagic;
public void DoMagic(string s)
{
BusinessObject bo = (BusinessObject)Activator.CreateInstance(Type.GetType("Module1+MyBusinessObject"));
MethodInfo mi = bo.GetType().GetMethod("DoMagic", BindingFlags.Public | BindingFlags.Instance);
// ArgumentException: Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type.
delDoMagic = (DoMagicDel)Delegate.CreateDelegate(typeof(DoMagicDel), null, mi);
delDoMagic(bo, s);
}
}
#endregion
}
Where Assembly A has a project reference to Assembly B but not vice versa. It works when I change first parameter DoMagicMel to type MyBusinessObject. But because assembly B doesn`t know this type of assembly A, this works only in my simplified example:
private delegate void DoMagicDel(MyBusinessObject bo, string s);
Any chance to get this working?
回答1:
ArgumentException: Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type.
Why does the following Delegate.CreateDelegate produce a runtime ArgumentException?
- Because the signature of
DoMagicDeldoes not match the signature of the method described by mi.
Any chance to get this working?
Yes, use
MakeGenericTypeto match the signature of mi:#region Assembly B public class MyDataObject { public delegate void DoMagicDel<T1>(T1 arg1, string arg2); private static Delegate delDoMagic; public void DoMagic(string s) { var bo = Activator.CreateInstance("Module1", "Module1.MyBusinessObject").Unwrap(); MethodInfo mi = bo.GetType().GetMethod("DoMagic", BindingFlags.Public | BindingFlags.Instance); var doMagicDelType = typeof(DoMagicDel<>).MakeGenericType(bo.GetType()); if (delDoMagic == null) delDoMagic = Delegate.CreateDelegate(doMagicDelType, null, mi); delDoMagic.DynamicInvoke(bo, s); } } #endregion
I hope I'm not too late ...
来源:https://stackoverflow.com/questions/21625922/create-open-instance-delegate-via-reflection