Что-то не так с динамическим ключевым словом в C# 4.0?

Существует некоторое странное поведение с C# 4.0 динамическое использование:

using System;

class Program {
  public void Baz() { Console.WriteLine("Baz1"); }
  static void CallBaz(dynamic x) { x.Baz(); }

  static void Main(string[] args) {
    dynamic a = new Program();
    dynamic b = new { Baz = new Action(() => Console.WriteLine("Baz2")) };

    CallBaz(a); // ok
    CallBaz(b); // ok
    CallBaz(a); // Unhandled Exception:
    // Microsoft.CSharp.RuntimeBinder.RuntimeBinderException:
    // The name 'Baz' is bound to a method and cannot be used like a property
  }
}

Я использую Предвыпускную версию Visual Studio 2010 года.

Действительно ли это - ошибка? Если это будет верно, то это будет зафиксировано в Выпуске?

50
задан casperOne 21 February 2010 в 09:50
поделиться

4 ответа

Это звучит как хорошая идея. Единственное, что меня беспокоит - нужно ли обновлять каждые 10 минут? Это также может замедлить процесс во время выполнения обновления. Обычно это делается в течение ночи (чтобы оказать наименьшее воздействие на других), или, если в течение дня, только в 3 фиксированных точках (скажем, 10 часов утра, 13 часов вечера и 16 часов дня).

-121--3702199-

Естественно, для большинства приложений корпоративного класса база данных транзакций всегда отделена от базы данных отчетов. Система транзакций настроена на OLTP, и база данных отчетности может быть денормирована в соответствии с требованиями сценариев отчетности. Так что это почти естественное предположение.

-121--3702201-

Я могу подтвердить, что это действительно ошибка. Краткое описание того, что происходит не так: в CallBaz есть один сайт вызова, который вызывается три раза. Этот callsite является InvokeMember, потому что это лучшее предположение компилятор может сделать учитывая синтаксис C #, несмотря на то, что он может, в действительности, разрешить GetMember, а затем Invoke.

Во время второго выполнения callsite это действительно является привязкой, которую находит среда выполнения. Таким образом, создается отсрочка для GetMember с последующим вызовом. Ошибка заключается в том, что эта отсрочка не ограничивается должным образом случаем, когда аргумент является анонимным типом. Таким образом, в третьем выполнении отсрочка запускается, и GetMember пытается привязаться к программе, что, конечно, не удается.

Спасибо, что нашли это. Как указывает Эрик, мы находимся здесь на очень позднем этапе, и становится трудно исправить проблемы, прежде чем мы отправимся. Но мы также хотим поставить правильный продукт. Я сделаю все, что в моих силах, чтобы решить эту проблему, хотя я не могу добиться успеха. Если вы придумаете что-то еще, пожалуйста, не стесняйтесь обращаться ко мне. =)

UPDATE:

Хотя я не могу гарантировать, как будет выглядеть окончательная версия VS 2010 и C # 4 при поставке, я могу сказать, что мне удалось протолкнуть это исправление. Текущая версия escrow build работает правильно для вашего кода. За исключением какой-то катастрофы, вы увидите, что это исправлено при освобождении. Еще раз спасибо. Я должен тебе пива.

32
ответ дан 7 November 2019 в 11:07
поделиться

Похоже на серьезную ошибку ...

Обратите внимание, что она отлично работает, если вы используете ExpandoObject вместо анонимного типа:

using System;
using System.Dynamic;

class Program {
  public void Baz() { Console.WriteLine("Baz1"); }
  static void CallBaz(dynamic x) { x.Baz(); }

  static void Main(string[] args) {
    dynamic a = new Program();
    dynamic b = new ExpandoObject();
    b.Baz = new Action(() => Console.WriteLine("Baz2"));

    CallBaz(a); // ok
    CallBaz(b); // ok
    CallBaz(a); // ok
  }
}

Таким образом, проблема кажется специфичной для анонимных объектов .. .

Очевидно, во втором вызове CallBaz (a) DLR все еще пытается получить доступ к Baz как к свойству, потому что это было свойство анонимного типа. Я подозреваю, что связыватель C # выполняет некоторое кеширование разрешения вызовов для повышения производительности, но в этом случае он явно не работает ...

8
ответ дан 7 November 2019 в 11:07
поделиться

То же что-то происходит со мной, я предлагаю вам сообщить об этом здесь .

2
ответ дан 7 November 2019 в 11:07
поделиться

Выглядит подозрительно. Отправлю на тестирование и посмотрим, что они скажут.

Просто чтобы оправдать ожидания: если это ошибка, и она еще не была обнаружена и исправлена, скорее всего, исправление не войдет в финальную версию.

Спасибо, что обратили на это наше внимание!

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

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