Много первой случайной Microsoft. До-диез. RuntimeBinderExceptions, брошенный при контакте с динамикой

У меня есть стандарт 'динамический словарь' класс типа в C# -

class Bucket : DynamicObject
{
    readonly Dictionary<string, object> m_dict = new Dictionary<string, object>();

    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        m_dict[binder.Name] = value;
        return true;
    }

    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        return m_dict.TryGetValue(binder.Name, out result);
    }
}

Теперь я называю его, следующим образом:

static void Main(string[] args)
{
    dynamic d = new Bucket();
    d.Name = "Orion"; // 2 RuntimeBinderExceptions
    Console.WriteLine(d.Name); // 2 RuntimeBinderExceptions
}

Приложение делает то, к чему Вы ожидали бы это, но вывод отладки похож на это:

A first chance exception of type 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' occurred in Microsoft.CSharp.dll
A first chance exception of type 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' occurred in Microsoft.CSharp.dll
'ScratchConsoleApplication.vshost.exe' (Managed (v4.0.30319)): Loaded 'Anonymously Hosted DynamicMethods Assembly'
A first chance exception of type 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' occurred in Microsoft.CSharp.dll
A first chance exception of type 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' occurred in Microsoft.CSharp.dll

Любая попытка получить доступ к динамическому участнику, кажется, производит a RuntimeBinderException к журналам отладки. В то время как я знаю, что исключениями первого шанса не является проблема в и себя, это действительно вызывает некоторые проблемы для меня:

  1. Мне часто устанавливали отладчик для "повреждения на исключениях", поскольку я пишу приложения WPF, и иначе все исключения заканчивают тем, что были преобразованы в a DispatcherUnhandledException, и вся фактическая информация, которую Вы хотите, потеряна. WPF сосет как этот.

  2. Как только я поразил любой код, это использует dynamic, выходной журнал отладки становится довольно бесполезным. Все полезные соединительные линии, о которых я забочусь, скрыты среди всего бесполезного RuntimeBinderExceptions

Есть ли любой способ, которым я могу выключить это или RuntimeBinder к сожалению, просто созданный как этот?

Спасибо, Orion

51
задан Orion Edwards 1 June 2010 в 15:02
поделиться

1 ответ

Каждый раз, когда разрешается свойство динамического объекта, среда выполнения пытается найти свойство, определенное во время компиляции. Из DynamicObject doco:

Вы также можете добавлять своих участников в классы, производные от DynamicObject класс. Если ваш класс определяет свойства, а также отменяет TrySetMember, динамический языковая среда выполнения (DLR) сначала использует языковая привязка для поиска статического определение свойства в классе. Если такого свойства нет, DLR вызывает метод TrySetMember.

RuntimeBinderException генерируется всякий раз, когда среда выполнения не может найти статически определенное свойство (т.е. что было бы ошибкой компилятора в 100% статически типизированном мире). Из статьи MSDN

... RuntimeBinderException представляет собой отказ связать в смысле обычная ошибка компилятора ...

Интересно, что если вы используете ExpandoObject , вы получите только одно исключение при попытке использовать свойство:

dynamic bucket = new ExpandoObject();
bucket.SomeValue = 45;
int value = bucket.SomeValue; //<-- Exception here

Возможно, ExpandoObject может быть альтернатива? Если это не подходит, вам нужно будет изучить реализацию IDynamicMetaObjectProvider , как ExpandoObject выполняет динамическую диспетчеризацию. Однако он не очень хорошо документирован, и MSDN отсылает вас к DLR CodePlex за дополнительной информацией.

26
ответ дан 7 November 2019 в 10:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: