Подтвердить что ты не робот

Как вы будете использовать динамический тип С# 4?

С# 4 будет содержать новое ключевое слово dynamic, которое добавит в С# динамические языковые функции.

Как вы планируете использовать его в своем коде, какой шаблон вы бы предложили? В какой части вашего текущего проекта он сделает ваш код чище или проще, или включит то, что вы просто не можете сделать (вне очевидного взаимодействия с динамическими языками, такими как IronRuby или IronPython)?

PS: Пожалуйста, если вам не нравится это дополнение С# 4, избегайте негативных комментариев.

Изменить: переосмыслив вопрос.

Классические методы динамического использования хорошо известны большинству пользователей С# stackoverflow. Я хочу знать, если вы думаете о конкретных новых моделях С#, где динамика может быть с пользой использована, не теряя слишком много С#.

4b9b3361

Ответ 1

Везде, где используется старомодное отражение, и читаемость кода была нарушена. И, как вы говорите, некоторые сценарии Interop (я иногда работаю с COM).

Это в значительной степени. Если можно избежать использования dynamic, его следует избегать. Проверка времени выполнения, производительность и т.д.

Несколько недель назад я вспомнил эту статью. Когда я впервые прочитал это, я был откровенно откровенен. Но я не понял, что я не знал, как использовать оператор на каком-то неизвестном типе. Я начал задаваться вопросом, что сгенерированный код будет для чего-то вроде этого:

dynamic c = 10;
int b = c * c;

Используя регулярное отражение, вы не можете использовать определенные операторы. Он генерировал довольно много кода, используя некоторые вещи из пространства имен Microsoft. Скажем, этот код намного проще читать:) Хорошо, что он работает, но он также был очень медленным: примерно в 10 000 раз медленнее обычного умножения (doh) и примерно в 100 раз медленнее, чем интерфейс ICalculator с методом Multiply.

Изменить - сгенерированный код для заинтересованных:

if (<Test>o__SiteContainer0.<>p__Sitea == null)
  <Test>o__SiteContainer0.<>p__Sitea =
    CallSite<Func<CallSite, object, object, object>>.Create(
      new CSharpBinaryOperationBinder(ExpressionType.Multiply,
        false, false, new CSharpArgumentInfo[] {
          new CSharpArgumentInfo(CSharpArgumentInfoFlags.None, null),
          new CSharpArgumentInfo(CSharpArgumentInfoFlags.None, null) }));
b = <Test>o__SiteContainer0.<>p__Site9.Target(
      <Test>o__SiteContainer0.<>p__Site9,
      <Test>o__SiteContainer0.<>p__Sitea.Target(
        <Test>o__SiteContainer0.<>p__Sitea, c, c));

Ответ 2

Динамическое ключевое слово - это упрощение кода, необходимого для двух сценариев:

  • С# для COM-взаимодействия
  • С# для динамического языка (JavaScript и т.д.) interop

В то время как может использоваться вне этих сценариев, возможно, не должен.

Ответ 3

Недавно я писал о динамических типах в С# 4.0, и среди прочего я упомянул о некоторых его потенциальных возможностях, а также о некоторых его проблемах. Сама статья слишком велика, чтобы вписаться сюда, но вы можете полностью ее прочитать на этом address.

В качестве краткого описания можно привести несколько полезных примеров использования (за исключением очевидного взаимодействия с библиотеками COM и динамическими языками, такими как IronPython):

  • чтение случайного XML или JSON в динамический объект С#. Структура .Net содержит классы и атрибуты для простого десериализации документов XML и JSON в объекты С#, но только если их структура статична. Если они динамичны и вам нужно открыть их поля во время выполнения, их можно было бы десериализовать только в динамические объекты..Net не предлагает эту функцию по умолчанию, но ее можно сделать сторонними инструментами, такими как jsonfx или DynamicJson
  • возвращает анонимные типы из методов. Анонимные типы имеют ограниченную область действия метода, в котором они определены, но это можно преодолеть с помощью динамического. Конечно, это опасно, поскольку вы будете подвергать объекты динамической структуре (без проверки времени компиляции), но в некоторых случаях это может быть полезно. Например, следующий метод считывает только два столбца из таблицы БД с использованием Linq to SQL и возвращает результат:

    public static List<dynamic> GetEmployees()
    {
      List<Employee> source = GenerateEmployeeCollection();
      var queyResult = from employee in source
                    where employee.Age > 20
                    select new { employee.FirstName, employee.Age };
    
      return queyResult.ToList<dynamic>();
    }
    
  • создать службы REST WCF, которые возвращают динамические данные. Это может быть полезно в следующем сценарии. Учтите, что у вас есть веб-метод, который возвращает данные, относящиеся к пользователю. Тем не менее, ваш сервис предоставляет довольно много информации о пользователях, и будет неэффективно просто возвращать все из них все время. Было бы лучше, если бы вы могли разрешить потребителям указывать нужные им поля, например, со следующим URL

    http://api.example.com/users?userId=xxxx&fields=firstName,lastName,age
    

    Проблема тогда возникает из-за того, что WCF будет возвращать только ответы клиентов, сделанные из сериализованных объектов. Если объекты являются статическими, то не будет возможности возвращать динамические ответы, поэтому необходимо использовать динамические типы. Однако здесь есть одна последняя проблема, и по умолчанию динамические типы не являются сериализуемыми. В статье есть образец кода, который показывает, как преодолеть это (опять же, я не размещаю его здесь из-за его размера).

В конце вы могли заметить, что два из упомянутых случаев использования требуют некоторых обходных решений или сторонних инструментов. Это заставляет меня думать, что, хотя команда .Net добавила очень крутую функцию в инфраструктуру, они могли бы добавить ее только с учетом COM и динамических языков. Это было бы позором, потому что динамические языки имеют некоторые сильные преимущества и обеспечивают их на платформе, которая сочетает их с сильными сильными типизированными языками, вероятно, поставит .Net и С# перед другими платформами разработки.

Ответ 4

Мигель де Иказа представил в своем блоге очень крутой вариант использования, здесь (источник включен):

dynamic d = new PInvoke ("libc");
d.printf ("I have been clicked %d times", times);

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

Ответ 5

Это также позволит нам избежать использования шаблона посетителя в некоторых случаях, поскольку теперь возможна многоотдача

public class MySpecialFunctions
{
  public void Execute(int x) {...}
  public void Execute(string x) {...}
  public void Execute(long x) {...}
}

dynamic x = getx();
var myFunc = new MySpecialFunctions();
myFunc.Execute(x);

... вызовет наилучшее совпадение метода во время выполнения, вместо того, чтобы разрабатываться во время компиляции

Ответ 6

Я буду использовать его для упрощения моего кода, который имеет дело с COM/Interop, где раньше мне приходилось указывать член для вызова, его параметры и т.д. (в основном, когда компилятор не знал о существовании функции, и мне нужно было описать его во время компиляции). С динамикой это становится менее громоздким, а код становится более компактным.