Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 列表<;对象>;vs列表<;动态>;_C#_Asp.net - Fatal编程技术网

C# 列表<;对象>;vs列表<;动态>;

C# 列表<;对象>;vs列表<;动态>;,c#,asp.net,C#,Asp.net,我需要创建对象(自定义类)的异构列表。我的第一个想法是创建一个列表,但我很快意识到这不是我想要的。我的下一个想法是列出,这似乎不是个坏主意。然而,我在做一些研究时遇到了这个问题,在这个例子中,他们使用List基本上做了我想要做的事情 除了在运行时计算动态和在编译时计算对象之外,列表和列表之间有什么区别?它们本质上不是一样吗?不同之处在于,如果您使用对象并试图访问对象的某个成员,那么这将是一个编译时错误(因为对象没有此成员)。为了工作,您需要知道类型是什么,并对其进行强制转换 使用dynamic,

我需要创建对象(自定义类)的异构
列表。我的第一个想法是创建一个
列表
,但我很快意识到这不是我想要的。我的下一个想法是列出,这似乎不是个坏主意。然而,我在做一些研究时遇到了这个问题,在这个例子中,他们使用
List
基本上做了我想要做的事情


除了在运行时计算
动态
和在编译时计算
对象
之外,
列表
列表
之间有什么区别?它们本质上不是一样吗?

不同之处在于,如果您使用对象并试图访问对象的某个成员,那么这将是一个编译时错误(因为对象没有此成员)。为了工作,您需要知道类型是什么,并对其进行强制转换

使用dynamic,您可以访问任何成员-无编译时错误。如果该成员在运行时不存在,则将是一个运行时错误。例如,如果你知道你的异端物体都有相同的成员,那么这就是方法

但是,如果是这种情况,还有另一个更明确的解决方案:您可以使用该成员定义一个接口,然后让所有异端对象实现它,并且您的列表可以是
list

请记住,由于动态类型解析,dynamic的性能可能会稍差。

在C#中有3种“通用”类型(尽管并非全部都是实类型):object、var和dynamic

对象

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

强调:对象是一种类型。对象可以是object类型,并且该类型有其方法,如ToString()。因为所有东西都继承自对象,所以所有东西都可以向上投射到对象中。当您将对象指定给对象引用时,您正在进行向上转换,就像将大象类型的对象指定给大象从动物继承的动物引用一样

  • obj在编译时被视为object类型,在运行时将被视为object类型(这是逻辑的,因为它是实际类型-obj被声明为object,因此只能属于该类型)
  • DoSomething()将导致编译时错误,因为对象没有此方法,而不管SomeType是否有此方法
Var

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

  • 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方法,但仍可以调用它并将任何对象作为参数传递,而不会出现编译时错误,这将引发异常,导致错误仅在运行时显示,并且可能仅在特定情况下显示-这是一个潜在的错误。因此,如果您在类的任何类型的公共接口中使用dynamic,那么您应该始终在运行时使用反射手动执行类型检查,仔细处理异常,或者一开始就不这样做


注意:当然,所引用的对象永远不会更改其类型。虽然obj可能是object,但它所指的x仍然是SomeType。

为什么需要在同一个列表中存储异构对象?只是好奇…你应该寻找动态vs对象,看看这个线程,它可能会回答你的答案我有一个类,其中一个属性是一个与该类相关的项集合,这些项不是相同的类型,而是作为一个组相关。顺便说一下,你能解释一下为什么
ISomeMarkerInterface
不好用吗?如果你只想简单地使用LINQ,你有没有看过带有List的Enumerable.OfType()?使用dynamic,您是否可以检查成员是否存在,并在不存在成员的情况下继续操作而不抛出错误?有点像在javascript中,如果(data.something){}
,你可以做类似于
的事情,这就是反射。您可以使用动态或不使用动态。查看GetType()、GetMethod()等+1,如果您沿着反射路线走,您可能只需要使用Object(但我仍然建议在上面使用marker接口)-1来说明
dynamic
不是实际类型(与
var
非常不同,后者不是实际类型,正如您正确地说的那样)
dynamic
无疑是C#中的一种类型,它甚至是一种静态类型,但是
dynamic
类型的对象将绕过静态类型检查。查看C语言规范的§4.7或此链接()了解更多信息。哎呀,我修复了它。我想我应该先检查一下D I虽然dynamic在分配运行时立即被解析为适当的类型,并且从来没有实际键入为“dynamic”,但显然不是这样。顺便说一下,如果遇到编译器错误,您需要添加对
Microsoft.CSharp.dll
的引用。
SomeType x = new SomeType();
dynamic obj = x;
obj.DoSomething();
public void f(dynamic x)
{ 
    x.DoSomething();
}