tags:

views:

193

answers:

1

In C# 4.0, there is a new DynamicObject.

It provides a "magic method" TryInvokeMember() that gets called when trying to call a method that does not exist.

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

What I would like to know is if TryInvokeMember() gets called when trying to call a protected method from outside the defining class.

I am contrasting the behaviour with PHP, which does call its equivalent "magic method" __call() in this situation.

+4  A: 

When you write a call that would invoke a method that is not accessible (using the standard C# access rules), then the inaccessible method won't be called and the runtime will call the TryInvokeMember (where you can handle the call in some other way). Here is an example, so that you can try it:

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);
  }
}

Now, we can create an instance of the object and try calling some of its methods:

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

So, if you call the base implementation of TryInvokeMember, the C# dynamic binder will fail when calling an inaccessible method, but you can define your own handling of the case in TryInvokeMember (by setting the result to some value and returning true).

Tomas Petricek
Just to clarify the issue. It throws an exception because you call a default binder. Just change "return base.TryInvoke" to something like "result = null; return true;" to avoid the exception. You probably didn't mean it, but now it looks like calling a protected method will always result in an exception (or is it my tech writer nit-picking?)
Alexandra Rusina
Thanks for the comment - I'll clarify the last sentence.
Tomas Petricek