Почему каждый отдельный динамический вызов приводит к двум исключениям и можно ли их подавить?

Учтите следующее:

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:

enter image description here

Теперь эти исключения явно перехватываются и обрабатываются внутри, потому что После этого вызывается метод TryInvokeMember . Тем не менее, если вы подпишетесь под мантрой «используйте исключения только в исключительных обстоятельствах», это может показаться неуместным и неуместным использованием исключений. В моем конкретном примере это не проблема, потому что одни и те же члены - Foo и Bar - вызываются неоднократно. Однако у меня есть другие сценарии, в которых члены гораздо менее статичны.

Можно ли что-нибудь сделать, чтобы среда выполнения вызывала TryInvokeMember без выдачи исключений?

6
задан Bill the Lizard 6 December 2011 в 16:57
поделиться