我需要创建一个异构的 List
对象(自定义类)。我的第一个想法是创建一个 List<ISomeMarkerInterface>
但我很快了解到这不是我想要的。我的下一个想法是 List<dynamic>
这似乎不是个坏主意。然而,我正在做一些研究并发现了这个 article about boxing and unboxing在这个例子中,他们基本上是在用 List<Object>
做我想做的事.
除了 dynamic
将在运行时进行评估,并且 Object
在编译时,List<dynamic>
之间有什么区别?和 List<Object>
?它们本质上不是一回事吗?
最佳答案
在 C# 中有 3 种“通用”类型(尽管并非全部都是真实类型):object、var 和 dynamic。
对象
一个实际类型,与任何其他类型一样,具有一个特殊规则:如果一个类型不继承,则它从对象 继承。由此可知,所有类型都直接或间接继承自object。
强调:对象是一种类型。对象可以是object 类型,并且该类型有其方法,如 ToString()。由于一切都继承自 object,因此一切都可以向上转换为 object。当您将一个对象分配给一个对象 引用时,您就是在进行向上转型,就像您将一个Elephant 类型对象分配给一个Animal 引用一样,其中< em>Elephant 继承自Animal。
SomeType x = new SomeType();
object obj = x;
obj.DoSomething();
- obj 在编译时被视为 object 类型,在运行时将是 object 类型(这是合乎逻辑的,因为它是一个实际类型 - obj 被声明为 object 所以只能是那个类型)
- obj.DoSomething() 会导致编译时错误,因为 object 没有这个方法,无论 SomeType 是否有。
变量
这不是实际类型,它只是“编译器,根据赋值的右侧为我找出类型”的简写。
SomeType x = new SomeType();
var obj = x;
obj.DoSomething();
- obj 在编译时被视为类型 SomeType ,并且在运行时将是类型 SomeType ,就像你有写成“SomeType”而不是“var”。
- 如果 SomeType 有一个方法 DoSomething(),此代码将起作用
- 如果 SomeType 没有该方法,代码将导致编译时错误
动态
这是一种告诉编译器禁用变量的编译时类型检查的类型。对象在编译时和运行时被视为具有动态类型。
SomeType x = new SomeType();
dynamic obj = x;
obj.DoSomething();
- obj 在编译和运行时是动态类型
- 如果 SomeType 有一个方法 DoSomething(),此代码将起作用
- 如果 SomeType 没有该方法,代码将编译,但在运行时抛出异常
请注意,如果使用不当,dynamic 很容易导致异常:
public void f(dynamic x) { x.DoSomething(); }
如果 x 的类型没有 DoSomething 方法,这将引发异常,但仍然可以调用它并传递任何对象作为没有编译时错误的参数,导致错误仅在运行时出现,并且可能仅在特定情况下出现 - 一个潜在的错误。因此,如果您在类的任何类型的公共(public)接口(interface)中使用动态,您应该始终在运行时使用反射手动进行类型检查,小心处理异常,或者一开始就不要这样做。
注意:当然,被引用的对象永远不会改变它的类型。虽然 obj 可能是 object,但它所指的 x 仍然是 SomeType。
关于c# - 列表<对象> 与列表<动态>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10379968/