列出<object> vs List <dynamic> </dynamic> </object>

时间:2012-04-30 07:26:46

标签: c# asp.net

我需要创建异构List个对象(自定义类)。我的第一个想法是创建一个List<ISomeMarkerInterface>但我很快就知道这不是我想要的。我的下一个想法是List<dynamic>,这似乎并不是一个坏主意。但是,我正在做一些研究并遇到了这个article about boxing and unboxing,在这个例子中,他们基本上正在使用List<Object>做我想做的事情。

除了dynamic将在运行时和Object在编译时进行评估,List<dynamic>List<Object>之间的区别是什么? Aren他们基本上是一回事吗?

2 个答案:

答案 0 :(得分:23)

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 没有该方法,代码将导致编译时错误

<强>动态

这是一种告诉编译器禁止对变量进行编译时类型检查的类型。在编译时和运行时将对象视为具有 dynamic 类型。

SomeType x = new SomeType();
dynamic obj = x;
obj.DoSomething();
  • obj在编译和运行时的动态类型
  • 如果 SomeType 有方法 DoSomething(),则此代码可以使用
  • 如果 SomeType 没有该方法,代码将编译,但在运行时抛出异常
  • 请注意,如果不小心使用,动态会非常容易导致异常:

    public void f(dynamic x)
    { 
        x.DoSomething();
    }
    

如果 x 属于没有 DoSomething 方法的类型,则会抛出异常,但仍然可以调用它并传递任何对象作为没有编译时错误的参数,导致错误仅在运行时显示,并且可能仅在特定情况下显示 - 潜在的错误。因此,如果在类的任何类型的公共接口中使用dynamic,则应始终使用反射在运行时手动键入 - 检查,小心处理异常,或者不首先执行此操作。

注意:被引用的对象当然不会改变其类型。虽然 obj 可能是对象,但它引用的 x 仍然是 SomeType

答案 1 :(得分:2)

不同之处在于,如果您使用对象并尝试访问对象的某个成员,则会出现编译时错误(因为对象没有此成员)。为了工作,你需要知道什么是类型并投下它。

使用动态,您可以访问任何成员 - 没有编译时错误。如果成员在运行时不存在,那将是运行时错误。如果您知道您的所有对象都具有相同的成员,那么这就是你要走的路。

但是,如果是这种情况,还有另一个更明确的解决方案:您可以使用此成员定义一个接口,然后让所有您的同等对象实现它,您的列表可以是List<IYourInterface>

请记住,由于动态类型分辨率很高,动态性能可能会稍微差一些。