This question already has answers here:
Difference between dynamic and System.Object
(4个答案)
已关闭6年。
谁能简要解释一下C#中“dynamic”和“object”关键字之间的区别?
如您所见,尽管obj存储一个整数,但是编译器不允许您在不进行强制转换的情况下执行任何数学运算。看起来强制转换可以帮助您确保确实有一个整数,但是没有。您可以强制转换为完全不同的类型,编译器将无法检测到它。如此一来,您将获得一个运行时异常。
因此,您必须执行明确的强制转换,它不能保证任何事情,因为编译器不允许您在没有强制转换的情况下运行程序。
动态:
这是C#4.0中新的dynamic关键字出现的地方。它告诉编译器不要对您的代码强制执行其他规则。
这是对象与动态对象之间的主要区别之一–使用动态对象,您可以告诉编译器对象的类型只能在运行时知道,并且编译器不会尝试进行干预。结果,您可以编写更少的代码。我想强调的是,这并不比使用原始object关键字更危险。但是,它也同样具有危险性,因此在处理对象(例如反射)时需要使用的所有类型检查技术也必须用于动态对象。
下一个经常出现的问题如下:“由于动态对象可以是任何东西,并且编译器不检查它是什么,这是否意味着您可以将动态对象传递给我毫不怀疑的方法/系统并它崩溃了吗?”
假设我们有一个简单的方法。
如您所见,尽管编译器允许您将动态对象传递给您的方法,但是如果方法的类型错误,则您的方法永远不会获得该对象。在实际调用该方法之前会引发异常。可以将动态对象传递给方法的唯一方法是,如果它包含必需的值(在这种情况下为字符串)。
同样,这与您使用object关键字获得的行为没有太大不同。
有人说读(int)obj并不难,那么为什么要动感的呢?好吧,在某些情况下,您必须执行太多的强制转换操作,这会使您的代码几乎不可读。在某些情况下,简单的转换还不够,您必须调用反射方法,例如InvokeMember或GetProperties。一个很好的例子是COM互操作,这就是为什么要对其进行修改以使用新的动态功能的原因(有关更多信息,请参见此“方法”。)
此外,动态关键字和动态语言运行时支持许多以前无法实现或难以实现的场景,包括与动态语言的互操作。在本博客的前面,我已经重点介绍了几种这样的场景:ExpandoObject的介绍和DynamicObject的创建包装器。
结论:
结论是,不必担心有人会通过使用动态功能来破坏您的代码。它不比object关键字危险(而且同样如此)危险。
因此,如果您经常使用object关键字并且必须执行大量转换和/或使用反射来调用对象的方法和属性,则可能应该看看dynamic关键字。在某些情况下,它比对象更方便,并且编写的代码更少。
(4个答案)
已关闭6年。
谁能简要解释一下C#中“dynamic”和“object”关键字之间的区别?
最佳答案
对象:
首先,让我们快速看一下object关键字。我不会谈论太多,因为它从C#1.0开始就出现了。此关键字不过是System.Object的快捷方式,System.Object是C#类层次结构中的根类型。 (但是,正如Eric Lippert在其博客文章中指出的那样,并非C#中的所有内容都源自对象。)这是一种强大的机制,因为您几乎可以将任何值分配给该类型的实例。
这是一个简短的示例,演示了使用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;
如您所见,尽管obj存储一个整数,但是编译器不允许您在不进行强制转换的情况下执行任何数学运算。看起来强制转换可以帮助您确保确实有一个整数,但是没有。您可以强制转换为完全不同的类型,编译器将无法检测到它。如此一来,您将获得一个运行时异常。
因此,您必须执行明确的强制转换,它不能保证任何事情,因为编译器不允许您在没有强制转换的情况下运行程序。
动态:
这是C#4.0中新的dynamic关键字出现的地方。它告诉编译器不要对您的代码强制执行其他规则。
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;
这是对象与动态对象之间的主要区别之一–使用动态对象,您可以告诉编译器对象的类型只能在运行时知道,并且编译器不会尝试进行干预。结果,您可以编写更少的代码。我想强调的是,这并不比使用原始object关键字更危险。但是,它也同样具有危险性,因此在处理对象(例如反射)时需要使用的所有类型检查技术也必须用于动态对象。
下一个经常出现的问题如下:“由于动态对象可以是任何东西,并且编译器不检查它是什么,这是否意味着您可以将动态对象传递给我毫不怀疑的方法/系统并它崩溃了吗?”
假设我们有一个简单的方法。
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);
有人说读(int)obj并不难,那么为什么要动感的呢?好吧,在某些情况下,您必须执行太多的强制转换操作,这会使您的代码几乎不可读。在某些情况下,简单的转换还不够,您必须调用反射方法,例如InvokeMember或GetProperties。一个很好的例子是COM互操作,这就是为什么要对其进行修改以使用新的动态功能的原因(有关更多信息,请参见此“方法”。)
此外,动态关键字和动态语言运行时支持许多以前无法实现或难以实现的场景,包括与动态语言的互操作。在本博客的前面,我已经重点介绍了几种这样的场景:ExpandoObject的介绍和DynamicObject的创建包装器。
结论:
结论是,不必担心有人会通过使用动态功能来破坏您的代码。它不比object关键字危险(而且同样如此)危险。
因此,如果您经常使用object关键字并且必须执行大量转换和/或使用反射来调用对象的方法和属性,则可能应该看看dynamic关键字。在某些情况下,它比对象更方便,并且编写的代码更少。
关于.net - C#中的 “dynamic”和 “object”关键字有什么区别? [复制],我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20995759/