C#中var和IEnumerable之间的区别?

时间:2013-06-17 07:49:17

标签: c# .net ienumerable var

我正在阅读this文章,了解var和IEnumerable之间的区别。作者写了四点如下

  1. 如果您想动态制作“自定义”类型,请使用Var类型。
  2. 当您已经知道查询结果的类型时,请使用IEnumerable。
  3. Var也适用于远程收集。
  4. IEnumerable适用于内存中的集合。
  5. 点不。 3& 4我不清楚。请通过示例

    帮助理解这一点

4 个答案:

答案 0 :(得分:6)

这里的一切都是错的,至少是这么简短:

  • 这是错误的,结果类型将始终是返回的类型,无论是否明确指定;
  • 如果您打算使用结果,无论如何都需要知道类型! var不会改变这一点;
  • 这第三项是纯粹的poppycock;它本身没有任何意义;
  • IEnumerable通常只是 代表内存中的集合(它没有必要,因为它只是一个集合的契约,无论它们的最终存储是什么这个想法很大程度上与这个问题的其余部分并列;

关于var的使用情况的说明,提供更广泛的概念:使用var通常只有在结果类型明显的情况下才是个好主意在当前的陈述中 - 我并不真正理解Darren的推理或者它将如何有用,但请考虑以下因素:

var results0 = new List<string>();    // assignment type is obvious 
var results1 = something.GetResult(); // read must investigate to know

答案 1 :(得分:3)

var是一个隐式键入变量的上下文关键字。当您使用IEnumerable<T>时,您明确声明要定义的类型,因为var将使用类型推断。

使用var而非LINQ从集合中返回某些内容时,我使用的是哪一种,更多的是编码样式IMO,我个人使用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>

答案 2 :(得分:1)

var只是一个隐式类型的局部变量。您只需让编译器确定类型。

var i = 10; // Implicitly typed
int j = 10; // Explicitly typed

使用匿名类型时,它也非常方便,例如

var anon = new { Foo = "Bar" };
Console.WriteLine(anon.Foo); // Puts "Bar" on console.

More information here.

答案 3 :(得分:1)

如果有人说var MyList = SomeStringCollection.ToList(); MyEnumerator = MyList.GetEnumerator(); , then the type of MyList will be列表, 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 {{1} } IEnumerable had been MyList.GetEnumerator(), the return type of IEnumerator`,具有引用语义

这种差异可能很重要,例如一个人有一个方法,从would have been读取五个项目。如果使用类型IEnumerator<String>的变量多次调用此类方法,则每次调用将读取枚举中的下五个项目。相反,如果使用类似IEnumerator<String>的值类型多次调用此类方法,则每次调用都会将枚举状态复制到实现List<String>.Enumerator的新堆对象,将该对象传递给该方法(将通过它读取五个项目,然后放弃该对象及其相关空间(使与原始变量关联的枚举状态不受影响)。

请注意,在99%的情况下,值枚举或引用语义在枚举器中同样可以接受;在大多数情况下,值语义会使代码运行得更快,并且很少会使代码运行速度变慢。此外,在某些情况下,知道枚举器将表现为值类型可能在语义上有用(例如,如果想要能够重复地重新枚举集合的一部分)。另一方面,对于使用IEnumerator<T>的实现的代码来说,了解他们可能正在使用的实现类型可能是一个好主意。