C#委托没有绑定到实例?
是否有存储的委托不绑定到一个对象怎么样,你可以用一个MethodInfo的一种方式?现在我正在存储一个MethodInfo,所以我可以给它一个调用该方法的对象。但我更希望它是一个代表。就像有一个属性告诉.net第一个参数是“this”?C#委托没有绑定到实例?
MethodInfo mi;
Action<string> func;
mi.Invoke(this,new object[]{str});
func(this, str); //Is this possible with a delegate?
你想要什么叫做open instance delegate。它不直接支持C#语言,但CLR支持它。
基本上,打开的实例委托与普通委托相同,但它在普通参数之前需要this
的额外参数,并且具有空目标(如静态方法的委托)。例如,打开实例相当于Action<T>
是:
delegate void OpenAction<TThis, T>(TThis @this, T arg);
这里有一个完整的例子:
void Main()
{
MethodInfo sayHelloMethod = typeof(Person).GetMethod("SayHello");
OpenAction<Person, string> action =
(OpenAction<Person, string>)
Delegate.CreateDelegate(
typeof(OpenAction<Person, string>),
null,
sayHelloMethod);
Person joe = new Person { Name = "Joe" };
action(joe, "Jack"); // Prints "Hello Jack, my name is Joe"
}
delegate void OpenAction<TThis, T>(TThis @this, T arg);
class Person
{
public string Name { get; set; }
public void SayHello(string name)
{
Console.WriteLine ("Hi {0}, my name is {1}", name, this.Name);
}
}
看一看this article了解更多详情。
C#不直接支持它。感谢您的信息:D。 – Will 2011-03-23 00:26:08
可以使用Delegate.CreateDelegate
方法来创建一个强类型的代表为MethodInfo
。
如果你不知道方法的在编译时签名,你可以创建一个Func<...>
使用反射,或创建调用MethodInfo
lambda表达式:
MethodInfo methodInfo = ...;
object thisObj = ...;
Func<object[]> callMethod = args => methodInfo.Invoke(thisObj, args);
(这就是所谓的钻营)
注意,这将仍然具有反射每个委托被调用时命中的表现,不像Delegate.CreateDelegate
。
没有考虑使用lambda使它更好,谢谢。 – Will 2011-03-23 00:22:34
委托实质上只是一个MethodInfo
(实际上,一个MethodBase
)和一个对象引用,其中有一些内部指针用于执行。所以,如果你有一个MethodInfo
,你实际上有一个未绑定的委托。你的具体用例是什么?
在功能上,是的,它大致相同。但是MethodInfo.Invoke比调用代表... – 2011-03-23 00:15:21
@Thomas Levesque的要慢得多:授予。对于重复呼叫,可以通过调用“委托”来改善性能。CreateDelegate()'来创建一个绑定的委托,但是我猜想对于绑定调用放弃绑定调用放弃模式,它不会提供任何性能优势。 – 2011-03-23 02:05:52
为什么不干脆
Action<T, string> unbound = (This, str) => This.Method(str);
这样你就可以
unbound(instanceA, "hello");
unbound(instanceB, "world");
甚至
Action<string> bound = str => unbound(instanceC, str);
你可以改一下用多一点的细节问题,我想我懂了部分但不当然。 – 2011-03-22 23:52:14
增加了我的意思的例子。基本上有可能有一个委托没有对象引用,并给它一个对象,当你打电话给它? – Will 2011-03-23 00:06:18
我改变了你的问题的标题,使其更清晰。随意回滚,如果你不喜欢它;) – 2011-03-23 00:14:08