List <Object> vs List <dynamic>

Jas*_*son 19 c# asp.net

我需要创建一个异构List的对象(自定义类).我的第一个想法是创造一个,List<ISomeMarkerInterface>但我很快就知道这不是我想要的.我的下一个想法是List<dynamic>,这似乎并不是一个坏主意.但是,我正在做一些研究并且遇到了关于装箱和拆箱的这篇文章,在这个例子中,他们基本上都在做我想要的东西List<Object>.

除了这样的事实dynamic会在运行时被评估Object在编译时,是什么样的区别List<dynamic>List<Object>?它们本质上不是一回事吗?

svi*_*nja 23

C#中有3种"通用"类型(尽管不是全部都是真实类型):object,var和dynamic.

宾语

实际类型,与任何其他类型一样,具有一个特殊规则:如果类型不继承,则它继承自object.由此可见,所有类型都直接或间接地从对象继承.

重点:对象是一种类型.一个目的可以是类型的对象,和类型有其方法,像的ToString().由于一切都从对象继承,所以一切都可以转化为对象.当您将对象分配给对象引用时,您正在进行向上转换,就像将Elephant类型对象分配给Elephant继承自AnimalAnimal引用一样.

SomeType x = new SomeType();
object obj = x;
obj.DoSomething();
Run Code Online (Sandbox Code Playgroud)
  • obj在编译时被视为类型为object,并且在运行时将是object类型(这是逻辑的,因为它是一个实际类型 - obj被声明为object,因此只能是该类型)
  • obj.DoSomething()将导致编译时错误,因为对象没有此方法,无论SomeType是否具有它.

瓦尔

这不是一个实际的类型,它只是"编译器的简写,根据赋值的右侧为我找出类型".

SomeType x = new SomeType();
var obj = x;
obj.DoSomething();
Run Code Online (Sandbox Code Playgroud)
  • obj在编译时被视为SomeType类型,并且在运行时将是SomeType类型,就像您编写了"SomeType"而不是"var"一样.
  • 如果SomeType有一个方法DoSomething(),这个代码将起作用
  • 如果SomeType没有该方法,则代码将导致编译时错误

动态

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

SomeType x = new SomeType();
dynamic obj = x;
obj.DoSomething();
Run Code Online (Sandbox Code Playgroud)
  • obj 在编译和运行时是动态类型
  • 如果SomeType有一个方法DoSomething(),这个代码将起作用
  • 如果SomeType没有该方法,代码将编译,但在运行时抛出异常
  • 请注意,如果不小心使用动态可能会非常容易导致异常:

    public void f(dynamic x)
    { 
        x.DoSomething();
    }
    
    Run Code Online (Sandbox Code Playgroud)

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

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

  • -1表示`dynamic`不是一个实际类型(与`var`非常不同,其中_isn't_是一个实际类型,正如你所说的那样).`dynamic`绝对是C#中的一个类型,它甚至是_static_类型,但是`dynamic`类型的对象将绕过静态类型检查.有关详细信息,请查看C#语言规范的§4.7或此链接(http://msdn.microsoft.com/en-us/library/dd264736.aspx). (4认同)