问题
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
DoMagicDel
does not match the signature of the method described by mi.
Any chance to get this working?
Yes, use
MakeGenericType
to 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