有人能简要解释一下C#中“dynamic”和“object”关键字的区别吗?
对象:
首先,让我们快速了解一下“object”关键字。我不会过多地谈论它,因为它从C# 1.0开始就存在了。这个关键字只是System.Object的一个快捷方式,而System.Object是C#类层次结构中的根类型。(然而,正如Eric Lippert在他的博客文章中指出的那样,并不是所有的C#都派生自object。)这是一个强大的机制,因为你可以将几乎任何值分配给这种类型的实例。
下面是一个简短的示例,演示了使用“object”关键字的一些好处和问题。
object obj = 10;
Console.WriteLine(obj.GetType());
// Prints System.Int32 because
// this is the type of the value stored in this object.
// A compiler error, because
// at compile time the type of obj is System.Object.
// obj = obj + 10;
// You need to explicitly cast obj to a necessary type.
obj = (int)obj + 10;
// However, this does not mean that you are really safe.
// You can cast to a wrong type
// and the compiler will not detect it.
// Here you get an exception at run time,
// because obj is an integer, not a string.
// obj = (string)obj + 10;
// You also get a run-time exception
// if you cast to a wrong numeric type,
// even if there is an implicit conversion in the language.
// obj = (double)obj + 10;
dynamic dyn = 10;
Console.WriteLine(dyn.GetType());
// Same as "object".
// Prints System.Int32 because
// this is the type of the value stored in this object.
// No compiler error, because
// the compiler does not try to identify
// the type of the dynamic object at compile time.
dyn = dyn + 10;
// Also, this operation will succeed for all numeric
// or other types that support a “+” operation.
dyn = 10.0;
dyn = dyn + 10;
dyn = "10";
dyn = dyn + 10;
public static void Print(string arg)
{
Console.WriteLine(arg);
}
Now let’s look at how you can pass a dynamic object to it.
dynamic dyn = 10;
// You get an exception at run time here.
Print(dyn);
可以看到,尽管编译器允许您将动态对象传递给方法,但如果它的类型不正确,则该方法永远不会得到此对象。在实际调用方法之前,会抛出异常。唯一的方法是,如果动态对象包含必要的值,即字符串,才能将其传递给您的方法。
dynamic dyn = "10";
Print(dyn);
再次强调,这与使用"object"关键字的行为并没有太大区别。
object obj = 10;
// Doesn't compile.
//Print(obj);
// Compiles, but there is an exception at run time.
//Print((string)obj);
// This code works because obj is now a string,
// but you still need a cast.
obj = "10";
Print((string)obj);
类型 dynamic 在大多数情况下的行为类似于类型 object。但是,包含类型为 dynamic 的表达式的操作不会被编译器解析或类型检查。编译器将有关操作的信息打包在一起,该信息稍后用于在运行时评估操作。作为此过程的一部分,类型为 dynamic 的变量被编译成类型为 object 的变量。因此,类型 dynamic 仅存在于编译时,而不是运行时。
请注意,此说明摘自 MSDN 页面。
object
恰恰就是那样:一个纯粹的 C# 对象,只有最少量的方法。在 .NET 中,它作为一切事物的内置基类(确保每个对象都至少拥有 ToString()
、Equals()
和 GetHashCode()
)。dynamic
对象则完全不同。在静态类型语言中,dynamic
允许延迟绑定属性和方法,带来了一些能力和更好的兼容性,例如动态类型语言 Python。