Consider the following:
using System;
using System.Dynamic;
using System.Linq;
namespace DynamicObjectTest
{
class Program
{
static void Main(string[] args)
{
dynamic dyn = new TestDynamic();
Console.ReadKey();
foreach (var i in Enumerable.Range(0, 100))
{
Console.WriteLine(dyn.Foo());
Console.WriteLine(dyn.Bar());
}
Console.ReadKey();
}
}
class TestDynamic : DynamicObject
{
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
if (binder.Name == "Foo")
{
result = "Bar";
return true;
}
else if (binder.Name == "Bar")
{
result = "Foo";
return true;
}
return base.TryInvokeMember(binder, args, out result);
}
}
}
When running this program, four exceptions of type RuntimeBinderException
are thrown. You can observe this either by breaking on all thrown exceptions (Debug/Exceptions.../check the Common Language Runtime Exceptions Throw checkbox) or by using perfmon:
Now these exceptions are obviously caught and handled internally because the TryInvokeMember
method is called afterwards. However, it seems heavy-handed and an inappropriate use of exceptions if you subscribe to the "use exceptions only in exceptional circumstances" mantra. For my specific example it's not really a problem because the same members - Foo
and Bar
- are repeatedly invoked. However, I have other scenarios in mind where the members are far less static.
Is there anything that can be done to help the runtime invoke TryInvokeMember
without throwing any exceptions?