Делает ли ключевое слово "dynamic" в C # 4.0 избыточность Generics? - PullRequest
8 голосов
/ 06 мая 2009

Я очень взволнован по поводу динамических функций в 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. «динамический» теперь позволяет методам возвращать анонимные типы, как в случае ниже?

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

круто, ура

EDIT:

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

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

Ответы [ 5 ]

17 голосов
/ 06 мая 2009

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

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

Что даст ключевое слово dynamic

  • более простой код (когда вы взаимодействуете с Excel, скажем ..) Вам не нужно указывать имя классов или объектную модель. Если вы вызываете правильные методы, среда выполнения позаботится о вызове этого метода, если он существует в объекте в то время. Компилятор позволяет вам уйти, даже если метод не определен. Однако это подразумевает, что это будет медленнее, чем вызов метода с проверкой компилятора / статической типизацией, поскольку CLR должен будет выполнить проверки перед выполнением вызова динамического поля / метода var.
  • Динамическая переменная может содержать различные типы объектов в разные моменты времени - вы не привязаны к определенному семейству или типу объектов.
16 голосов
/ 06 мая 2009

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

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

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

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

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

Для всех остальных случаев дженерики и обычные C # - это путь.

8 голосов
/ 06 мая 2009

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

6 голосов
/ 06 мая 2009

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

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

3 голосов
/ 06 мая 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...