Ответ 1
В С#: объект, var и динамика есть 3 "общих" типа (хотя не все являются реальными типами).
Объект
Фактический тип, как и любой другой тип, с одним специальным правилом: если тип не наследует, он наследует объект. Из этого следует, что все типы наследуются от объекта, прямо или косвенно.
Акцент: объект - это тип. Объект может быть объекта типа, а тип имеет свои методы, такие как ToString(). Поскольку все наследуется от объекта, все может быть выросло в объект. Когда вы назначаете объект объектной ссылке, вы делаете восходящий поток точно так же, как если вы назначаете объект типа Elephant на ссылку Animal, где Elephant наследуется от Animal.
SomeType x = new SomeType();
object obj = x;
obj.DoSomething();
- obj рассматривается как объект типа во время компиляции и будет иметь объект типа во время выполнения (что является логическим, поскольку он является фактическим типом - obj объявляется как объект, поэтому может быть только такого типа)
- obj.DoSomething() вызовет ошибку времени компиляции, поскольку объект не имеет этого метода, независимо от того, имеет ли его тип SomeType.
Var
Это не фактический тип, это просто сокращение для "компилятора, укажите тип для меня, основанный на правой стороне задания".
SomeType x = new SomeType();
var obj = x;
obj.DoSomething();
- obj рассматривается как тип SomeType во время компиляции и будет иметь тип SomeType во время выполнения, точно так же, как если бы вы написали "SomeType" вместо "var".
- Если SomeType имеет метод DoSomething(), этот код будет работать
- Если SomeType не имеет метода, код вызовет ошибку времени компиляции
Динамический
Это тип, который сообщает компилятору отключить проверку типа компиляции по переменной. Объект рассматривается как имеющий тип dynamic во время компиляции и времени выполнения.
SomeType x = new SomeType();
dynamic obj = x;
obj.DoSomething();
- obj имеет тип dynamic при компиляции и времени выполнения
- Если SomeType имеет метод DoSomething(), этот код будет работать
- если SomeType не имеет метода, код будет компилироваться, но вызывать исключение во время выполнения
-
Обратите внимание, что динамика может очень легко вызвать исключения, если используется небрежно:
public void f(dynamic x) { x.DoSomething(); }
Это вызовет исключение, если x имеет тип, который не имеет метода DoSomething, но все равно можно вызвать его и передать любой объект в качестве параметра без ошибки времени компиляции, вызывая ошибку, которая отображается только во время выполнения и, возможно, только в определенных обстоятельствах - потенциальная ошибка. Поэтому, если вы используете динамику в любом виде открытого интерфейса класса, вы всегда должны вручную вводить проверку во время выполнения с помощью отражения, тщательно разбираться с исключениями или не делать этого в первую очередь.
Примечание: объект, на который ссылается, никогда не меняет свой тип, конечно. Хотя obj может быть объектом, x, к которому он относится, по-прежнему является SomeType.