Делает ли ключевое слово C # 4.0 dynamic Generics избыточным?

Мне очень нравятся динамические функции C # (динамическое ключевое слово C # 4 - почему бы и нет?), особенно потому, что в некоторых частях моего кода библиотеки я использую много рефлексии.

У меня двоякий вопрос:

1. заменяет ли динамический тип Generics, как в приведенном ниже случае?

Метод дженериков:

public static void Do_Something_If_Object_Not_Null<SomeType>(SomeType ObjToTest) {
        
        //test object is not null, regardless of its Type
        if (!EqualityComparer<SomeType>.Default.Equals(ObjToTest, default(SomeType))) {
            //do something
        }
    }

динамический метод (??):

public static void Do_Something_If_Object_Not_Null(dynamic ObjToTest) {

        //test object is not null, regardless of its Type?? but how?
        if (ObjToTest != null) {
            //do something
        }
    }

2. позволяет ли теперь dynamic методам возвращать анонимные типы, как в случае ниже?

 public static List<dynamic> ReturnAnonymousType() {
        return MyDataContext.SomeEntities.Entity.Select(e => e.Property1, e.Property2).ToList();
    }

круто, ура

РЕДАКТИРОВАТЬ:

Поразмыслив над своим вопросом еще немного, и в свете ответов я вижу, что полностью испортил основной общий / динамический вопрос. Они действительно совершенно разные. Так что да, спасибо за всю информацию.

А как насчет пункта 2?


person andy    schedule 06.05.2009    source источник


Ответы (5)


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

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

Кроме того, dynamic - это действительно особый случай object, поэтому бокс вступает в игру, но уже с удвоенной силой.

На самом деле вам следует ограничить использование dynamic несколькими случаями:

  • COM-взаимодействие
  • Взаимодействие DLR
  • возможно легкая утиная печать
  • возможно некоторые общие операторы

Во всех остальных случаях подойдут универсальные шаблоны и обычный C #.

person Marc Gravell    schedule 06.05.2009
comment
Еще одно удивительно полезное использование для динамики: взаимодействие JSON в веб-ситуациях RESTful, особенно если рассматриваемый JSON сильно колеблется от вызова к вызову. Существуют библиотеки, которые будут сериализовать и десериализовать JSON в / из динамического объекта. - person Randolpho; 31.12.2011

Чтобы ответить на ваш вопрос. Нет.

  • Generics дает вам «повторное использование алгоритма» - вы пишете код независимо от типа данных. ключевое слово dynamic ничего с этим не делает. Я определяю List<T>, а затем могу использовать его для списка строк, целых чисел и т. Д.
  • Безопасность типов: споры о проверке всего времени компиляции. Динамические переменные не будут предупреждать вас предупреждениями / ошибками во время компиляции, если вы сделаете ошибку, они просто взорвутся во время выполнения, если метод, который вы пытаетесь вызвать, отсутствует. Споры о статической и динамической типизации
  • Производительность. Generics значительно повышает производительность алгоритмов / кода, использующих типы значений. Это предотвращает весь цикл упаковки-распаковки, который стоит нам pre-Generics. Dynamic тоже ничего не делает.

Ключевое слово dynamic даст вам

  • более простой код (если вы взаимодействуете с Excel, скажем ...). Вам не нужно указывать имена классов или объектной модели. Если вы вызываете правильные методы, среда выполнения позаботится о вызове этого метода, если он существует в объекте в это время. Компилятор позволяет вам уйти, даже если метод не определен. Однако это означает, что это будет медленнее, чем выполнение проверенного компилятором / статического вызова метода, поскольку CLR должна будет выполнить проверки перед вызовом динамического поля / метода var.
  • Динамическая переменная может содержать разные типы объектов в разные моменты времени - вы не привязаны к определенному семейству или типу объектов.
person Gishu    schedule 06.05.2009
comment
спасибо Гишу, отличный ответ. Между вами и Марком было 50/50. ТАК действительно должен допускать более одного ответа, верно? ... разберись. еще раз спасибо - person andy; 07.05.2009

Чтобы ответить на ваш первый вопрос, обобщенные типы - это разрешенные во время компиляции, динамические типы во время выполнения. Так что есть определенная разница в безопасности типов и скорости.

person Peter van der Heijden    schedule 06.05.2009
comment
Для полноты, универсальные типы в .NET предоставляются средой выполнения, и вы можете указать аргументы универсального типа во время выполнения, если вам нужно. - person Marc Gravell; 06.05.2009
comment
@ Питер: спасибо, Питер. Я больше думал о реализации. Хотя теперь я вижу, что на самом деле использование динамических вместо Generics, как мой пример, было бы похоже на использование Object - person andy; 07.05.2009

Динамические классы и дженерики - это совершенно разные концепции. С помощью дженериков вы определяете типы во время компиляции. Они не меняются, они не динамичны. Вы просто помещаете «заполнитель» в некоторый класс или метод, чтобы вызывающий код определял тип.

Динамические методы определяются во время выполнения. У вас нет безопасности типов во время компиляции. Динамический класс аналогичен тому, как если бы у вас были ссылки на объекты и методы вызова по его строковым именам с использованием отражения.

person Stefan Steinegger    schedule 06.05.2009

Ответ на второй вопрос: вы можете возвращать анонимные типы в C # 3.0. Приведите тип к объекту, верните его и используйте отражение для доступа к его членам. Ключевое слово dynamic - это просто синтаксический сахар для этого.

person Niki    schedule 06.05.2009
comment
спасибо ники. Итак, в C # 4.0, могу ли я вернуть динамический вместо объекта, а затем не использовать отражение? - person andy; 07.05.2009
comment
Да, ты можешь. Используйте динамический в качестве возвращаемого типа для вашего метода, возвращающего анонимный тип. Затем вы можете получить доступ к членам без использования отражения. - person Maggie; 06.06.2011