C#4.0 - 在动态对象上调用受保护的方法是否会调用TryInvokeMember()?

Jam*_*mie 5 c# dynamic magic-methods

在C#4.0中,有一个新的DynamicObject.

它提供了一个"魔术方法"TryInvokeMember(),它在尝试调用不存在的方法时被调用.

http://msdn.microsoft.com/en-us/library/system.dynamic.dynamicobject.tryinvokemember%28VS.100%29.aspx

我想知道的是,当尝试从定义类之外调用受保护的方法时,是否调用TryInvokeMember().

我将这种行为与PHP形成对比,PHP在这种情况下确实调用了它的等效"魔术方法"__call().

Tom*_*cek 6

当你写一个调用,将调用不可访问方法(使用标准的C#访问规则),然后人迹罕至的方法将不会被调用,运行时将调用TryInvokeMember(在那里你可以处理一些其他的方式调用) .这是一个示例,以便您可以尝试:

class Test : DynamicObject {
  public void Foo() {
    Console.WriteLine("Foo called");
  }
  protected void Bar() {
    Console.WriteLine("Bar called");
  }

  public override bool TryInvokeMember
      (InvokeMemberBinder binder, object[] args, out object result) {
    Console.WriteLine("Calling: " + binder.Name);
    return base.TryInvokeMember(binder, args, out result);
  }
}
Run Code Online (Sandbox Code Playgroud)

现在,我们可以创建对象的实例并尝试调用它的一些方法:

dynamic d = new Test();
d.Foo(); // this will call 'Foo' directly (without calling 'TryInvokeMember')
d.Bar(); // this will call 'TryInvokeMember' and then throw exception
Run Code Online (Sandbox Code Playgroud)

因此,如果调用base实现TryInvokeMember,C#动态绑定器在调用不可访问的方法时将失败,但您可以定义自己的情况处理TryInvokeMember(通过设置result为某个值并返回true).