Когда следует использовать динамическое ключевое слово в c # 4.0? - PullRequest
52 голосов
/ 20 апреля 2010

Когда следует использовать динамическое ключевое слово в c # 4.0? ....... Любой хороший пример с динамическим ключевым словом в c # 4.0, который объясняет его использование ....

Ответы [ 7 ]

37 голосов
/ 20 апреля 2010

Динамический следует использовать только , если не использовать это больно . Как в библиотеках MS Office. Во всех остальных случаях этого следует избегать, так как проверка типа компиляции полезна. Ниже приведена хорошая ситуация с использованием динамического.

  1. Вызов метода javascript из Silverlight.
  2. COM-взаимодействие.
  3. Возможно чтение Xml, Json без создания пользовательских классов.
11 голосов
/ 14 января 2015

Как насчет этого? Что-то, что я искал и удивлялся, почему так сложно обойтись без «динамического».

interface ISomeData {}
class SomeActualData : ISomeData {}
class SomeOtherData : ISomeData {}

interface ISomeInterface
{
    void DoSomething(ISomeData data);
}

class SomeImplementation : ISomeInterface
{
    public void DoSomething(ISomeData data)
    {
        dynamic specificData = data;
        HandleThis( specificData );
    }
    private void HandleThis(SomeActualData data)
    { /* ... */ }
    private void HandleThis(SomeOtherData data)
    { /* ... */ }

}

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

Эквивалент неиспользования dynamic будет:

    public void DoSomething(ISomeData data)
    {
        if(data is SomeActualData)
          HandleThis( (SomeActualData) data);
        else if(data is SomeOtherData)
          HandleThis( (SomeOtherData) data);
        ...
        else
         throw new SomeRuntimeException();
    }
6 голосов
/ 23 января 2017

Как описано в здесь, динамика может упростить использование плохо спроектированных внешних библиотек: Microsoft предоставляет пример сборки Microsoft.Office.Interop.Excel.А с помощью dynamic вы можете избежать многих раздражающих явных приведений при использовании этой сборки.

Кроме того, в отличие от @ user2415376, это определенно не способ обработки интерфейсов, так как у нас уже реализован полиморфизм изначало дня языка!
Вы можете использовать

  ISomeData specificData = data;

вместо

dynamic specificData = data;

Кроме того, это гарантирует, что вы не передадите объект данных неправильного типа.

3 голосов
/ 02 января 2017

Проверьте это сообщение в блоге , в котором говорится о динамических ключевых слов в c #. Вот суть:

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

Рассмотрим недостатки:

  1. Нет проверки типов во время компиляции, это означает, что, если вы не уверены на 100% в своих модульных тестах (кашель), вы рискуете.

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

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

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

1 голос
/ 22 февраля 2017

Я хотел бы скопировать отрывок из поста проекта кода, который определяет, что:

Зачем использовать динамический?

В статически типизированном мире, динамическое дает разработчикам много веревки повеситься. При работе с объектами, типы которых могут быть известный во время компиляции, вы должны вообще избегать динамического ключевого слова расходы. Ранее я сказал, что моя первоначальная реакция была отрицательной, так что изменило мое решение? По словам Маргрет Этвуд, контекст - это все. когда статическая типизация, динамическая не имеет смысла. Если ты имея дело с неизвестным или динамическим типом, часто необходимо общаться с ним через отражение. Светоотражающий код не легко прочитал, и имеет все подводные камни динамического типа выше. В этом контекст, динамика имеет большой смысл. [More]

Хотя некоторые характеристики ключевого слова Dynamic:

  1. Динамически типизированный - Это означает, что тип объявленной переменной определяется компилятором во время выполнения.
  2. Нет необходимости инициализировать во время объявления.

например.,

dynamic str; 

str=”I am a string”; //Works fine and compiles

str=2; //Works fine and compiles
  1. Ошибки обнаруживаются во время выполнения

  2. Intellisense недоступен, поскольку тип и связанные с ним методы и свойства могут быть известны только во время выполнения. [https://www.codeproject.com/Tips/460614/Difference-between-var-and-dynamic-in-Csharp]

1 голос
/ 22 февраля 2017

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

0 голосов
/ 03 мая 2018

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

Я перенес некоторый код из VB6 в C #. Этот перенесенный код все еще был необходим для вызова других методов на объектах VB6 через COM-взаимодействие.

Классы, которые нужно вызвать, выглядели так:

class A
{
    void Foo() {...}
}

class B
{
    void Foo() {...}
}

(то есть, именно так классы VB6 выглядят в C # через COM-взаимодействие; в частности, COM-вызываемая оболочка, которая была автоматически сгенерирована).

Поскольку A и B не зависят друг от друга, вы не можете привести их друг к другу, и у них нет общего базового класса (COM не поддерживает то, что AFAIK и VB6 определенно не поддерживают. И они не реализовали общий интерфейс - см. ниже).

Исходный код VB6, который был перенесен, сделал это:

' Obj must be either an A or a B 
Sub Bar(Obj As Object) 
    Call Obj.Foo()
End Sub

Теперь в VB6 вы можете передавать вещи как Object, и среда выполнения выяснит, есть ли у этих объектов метод Foo() или нет. Но в C # буквальный перевод будет:

// Obj must be either an A or a B 
void Bar(object Obj) 
{
    Obj.Foo();
}

Что НЕ будет работать. Он не скомпилируется, потому что object не имеет метода с именем "Foo", и C #, будучи безопасным с точки зрения типов, этого не допустит.

Таким образом, простым «исправлением» было использование dynamic, например:

// Obj must be either an A or a B 
void Bar(dynamic Obj) 
{
    Obj.Foo();
}

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

Я бы не одобрил это для нового кода, но в этой ситуации (которая, я думаю, нередко судят по другим ответам здесь) это было ценно.

Рассмотрены альтернативы:

  • Использование отражения для вызова Foo (). Вероятно, будет работать, но больше усилий и меньше читабельности.

  • Модификации библиотеки VB6 здесь не было, но, возможно, мог бы быть подход для определения A и B с точки зрения общего интерфейса, который поддерживали бы VB6 и COM. Но использовать динамику было намного проще.


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

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