Учтите следующее:
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);
}
}
}
При запуске этой программы четыре исключения типа RuntimeBinderException
брошены. Вы можете наблюдать это, либо отключив все выброшенные исключения (Debug / Exceptions ... / отметьте флажок Common Language Runtime Exceptions Throw), либо используя perfmon:
Теперь эти исключения явно перехватываются и обрабатываются внутри, потому что После этого вызывается метод TryInvokeMember
. Тем не менее, если вы подпишетесь под мантрой «используйте исключения только в исключительных обстоятельствах», это может показаться неуместным и неуместным использованием исключений. В моем конкретном примере это не проблема, потому что одни и те же члены - Foo
и Bar
- вызываются неоднократно. Однако у меня есть другие сценарии, в которых члены гораздо менее статичны.
Можно ли что-нибудь сделать, чтобы среда выполнения вызывала TryInvokeMember
без выдачи исключений?