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

时间:2010-03-04 21:23:13

标签: 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()。

1 个答案:

答案 0 :(得分: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);
  }
}

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

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

因此,如果您调用base的{​​{1}}实现,则在调用不可访问的方法时C#动态绑定器将失败,但您可以在TryInvokeMember中定义自己对案例的处理(通过将TryInvokeMember设置为某个值并返回result)。