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

Почему С# динамический тип статический?

При чтении и изучении динамического ключевого слова я нашел следующую строку в [MSDN] (в Использование динамического типа (Руководство по программированию на С#)):

Тип - это статический тип, но объект типа dynamic обходит проверку статического типа. В большинстве случаев он функционирует так, как будто он имеет объект типа.

В чем смысл статичности в приведенной выше строке и как она обходит проверку статического типа?

4b9b3361

Ответ 1

Это статическая типизация:

string foo = "bar";

foo теперь является строкой, поэтому это приведет к ошибке времени компиляции:

foo = 1;

Даже если вы используете var, он все еще статически напечатан:

var foo = "bar";     // foo is now a string
foo = 1;             // still a compile time error

Использование ключевого слова dynamic означает, что тип не будет статическим и может быть изменен, поэтому теперь вы можете сделать это:

dynamic foo = "bar";   
foo = 1;              // this is now fine.

Теперь, почему он говорит, что "тип - это статический тип", потому что во многих динамических языках (например, Javascript) вы можете сделать что-то вроде этого:

var foo = { bar: 1 };

Создает объект с свойством "bar", а затем вы можете сделать это:

foo.la = 2;

Что добавляет новое свойство объекту в foo. Но если вы попробуете тот же трюк в С#

dynamic foo = new SomeClassThatDoesntHaveABarProperty();
foo.bar = 2;          // runtime error

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

Если вам нужен этот тип функциональности, вам нужно посмотреть ExpandoObject

Как говорится в описании, dynamic во многих случаях функционирует как объект. Вы можете сделать это:

dynamic foo = new Foo();
foo = new Bar();

Точно так же:

object foo = new Foo();
foo = new Bar();

Но разница возникает, когда вы хотите использовать свойства или методы. С динамическим я могу это сделать:

dynamic foo = new Foo();
foo.FooMethod();          // Note: You WILL get a runtime exception if foo doesn't have a FooMethod

Но с объектом мне нужно будет сделать это:

object foo = new Foo();
((Foo)foo).FooMethod();    // Note: I HAVE to know the type at compile time here

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

Ответ 2

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

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