C# 如何为具有空目标的实例方法创建委托?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/951624/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to create a delegate to an instance method with a null target?
提问by thecoop
I've noticed that the Delegate class has a Target property, that (presumably) returns the instance the delegate method will execute on. I want to do something like this:
我注意到 Delegate 类有一个 Target 属性,它(大概)返回委托方法将在其上执行的实例。我想做这样的事情:
void PossiblyExecuteDelegate(Action<int> method)
{
if (method.Target == null)
{
// delegate instance target is null
// do something
}
else
{
method(10);
// do something else
}
}
When calling it, I want to do something like:
调用它时,我想做如下事情:
class A
{
void Method(int a) {}
static void Main(string[] args)
{
A a = null;
Action<int> action = a.Method;
PossiblyExecuteDelegate(action);
}
}
But I get an ArgumentException (Delegate to an instance method cannot have a null 'this') when I try to construct the delegate. Is what I want to do possible, and how can I do it?
但是当我尝试构造委托时,我得到了一个 ArgumentException(实例方法的委托不能有一个 null 'this')。我想做的事情是否可行,我该怎么做?
采纳答案by thecoop
Ahah! found it!
啊啊!找到了!
You can create an open instance delegate using a CreateDelegateoverload, using a delegate with the implicit 'this' first argument explicitly specified:
您可以使用CreateDelegate重载创建一个开放实例委托,使用一个显式指定隐式“this”第一个参数的委托:
delegate void OpenInstanceDelegate(A instance, int a);
class A
{
public void Method(int a) {}
static void Main(string[] args)
{
A a = null;
MethodInfo method = typeof(A).GetMethod("Method");
OpenInstanceDelegate action = (OpenInstanceDelegate)Delegate.CreateDelegate(typeof(OpenInstanceDelegate), a, method);
PossiblyExecuteDelegate(action);
}
}
回答by Adam Robinson
In order to do this you would have to pass a static
method to PossiblyExecuteDelegate()
. This will give you a null
Target
.
为此,您必须将static
方法传递给PossiblyExecuteDelegate()
. 这会给你一个null
Target
.
class A
{
void Method(int a) {}
static void Method2(int a) {}
static void Main(string[] args)
{
PossiblyExecuteDelegate(A.Method2);
A a = new A();
PossiblyExecuteDelegate(a.Method);
}
}
Edit:It ispossible to pass a delegate to an instance method with no target via reflection, but not using standard compiled code.
编辑:它是可以通过反射到委托传递给一个实例方法没有目标,但不是使用标准编译的代码。
回答by lidqy
It is possible with Delegate.CreateDelegate, exactly with the overload with the signature:
CreateDelegate (Type, object, MethodInfo)
使用 Delegate.CreateDelegate 是可能的,完全使用带有签名的重载:
CreateDelegate (Type, object, MethodInfo)
If you specify "null" for the second parameter (target) then you have to put an extra parameter into the delegate type, that specifies the instance type, and when you invoke the delegate, the instance has to be passed as first argument, followed by the "real" parameters of the method.
如果您为第二个参数(目标)指定“null”,那么您必须将一个额外的参数放入委托类型中,该参数指定实例类型,并且当您调用委托时,该实例必须作为第一个参数传递,然后通过方法的“真实”参数。
class Test
{
public int AddStrings(string a, string b)
{
return int.Parse(a) + int.Parse(b);
}
static void Main()
{
var test = new Test();
var methodInfo = test.GetType().GetMethod("AddStrings");
// note the first extra parameter of the Func, is the owner type
var delegateType = typeof(Func<Test, string, string, int>);
var del = Delegate.CreateDelegate(delegateType, null, methodInfo);
var result = (int)del.DynamicInvoke(test, "39", "3");
}
}