我正在阅读这篇文章以了解 var 和 IEnumerable 之间的区别。作者写了如下四点
- 当您想动态创建“自定义”类型时,请使用 Var 类型。
- 当您已经知道查询结果的类型时,请使用 IEnumerable。
- Var 也适用于远程收集。
- IEnumerable 适用于内存收集。
点号 3和4我不清楚。请通过示例帮助理解这些要点
我正在阅读这篇文章以了解 var 和 IEnumerable 之间的区别。作者写了如下四点
点号 3和4我不清楚。请通过示例帮助理解这些要点
这里一切都错了,至少简单地说:
var
不会改变这一点;IEnumerable
通常只代表一个内存中的集合(它不必,请注意,因为它只是一个要遵守的集合的合同,无论它们的最终存储如何),并且这个想法在很大程度上与这个问题的其余部分并列;但是,关于使用的注释var
,以提供更广泛的概念:使用var
通常仅在基于当前语句的结果类型显而易见时才是一个好主意-我并不真正理解达伦的推理或这将如何有用,但请考虑以下几点:
var results0 = new List<string>(); // assignment type is obvious
var results1 = something.GetResult(); // read must investigate to know
var
是隐式类型变量的上下文关键字。当您使用时,IEnumerable<T>
您明确说明要定义的类型,因为 var 将使用类型推断。
您使用哪个并没有真正的区别,更多的是一种编码风格 IMO,我个人在使用而不是orvar
从集合中返回某些东西时使用。LINQ
IEnumerable<T>
IQueryable<T>
var value5 = list.Where(i => i == 5).ToList();
IEnumerable<int> value5 = list.Where(i => i == 5).ToList();
两者都将产生相同的输出。
关于第 3 点和第 4 点。我不认为 IEnumerable 对内存集合有任何好处。在幕后,CLR
将在运行时推断变量类型(使用 var 时),很可能是IEnumerable<T>
.
var
只是一个隐式类型的局部变量。您只需让编译器确定类型。
var i = 10; // Implicitly typed
int j = 10; // Explicitly typed
在使用匿名类型时,它也非常方便,例如。
var anon = new { Foo = "Bar" };
Console.WriteLine(anon.Foo); // Puts "Bar" on console.
如果有人说var MyList = SomeStringCollection.ToList()
;MyEnumerator = MyList.GetEnumerator(); , then the type of
MyList will be
List , and the type of
MyEnumerator will be
List.Enumerator , which is a *value type* that implements
IEnumerator , and will thus exhibit *value semantics*. If the type of
MyList had been
IEnumerable , the return type of
MyList.GetEnumerator() would have been
IEnumerator`,具有引用语义。
如果例如有一种方法可以从IEnumerator<String>
. 如果使用 type 变量多次调用这样的方法IEnumerator<String>
,则每次调用都会从枚举中读取接下来的五个项目。相反,如果使用类似的值类型多次调用此类方法List<String>.Enumerator
,则每次调用都会将枚举状态复制到实现的新堆对象IEnumerator<T>
,将该对象传递给方法(将通过它读取五个项目),然后放弃该对象及其关联空间(不影响与原始变量关联的枚举状态)。
请注意,在大约 99% 的情况下,值语义或引用语义在枚举器中同样可以接受;在大多数情况下,值语义会使代码运行得更快,而且很少会使代码运行得更慢。此外,在某些情况下,知道枚举器将表现为值类型在语义上可能是有用的(例如,如果希望能够重复地重新枚举集合的一部分)。另一方面,对于使用 的实现的代码,IEnumerator<T>
了解他们可能使用的实现类型可能是一个好主意。