简体   繁体   中英

Difference between var and IEnumerable in C#?

I am reading this article to understand difference between var and IEnumerable. Author wrote four points like following

  1. Use Var type when you want to make a "custom" type on the fly.
  2. Use IEnumerable when you already know the type of query result.
  3. Var is also good for remote collection.
  4. IEnumerable is good for in-memory collection.

point no. 3 & 4 is not clear to me. Please help to understand these point with examples

Everything is wrong here, so briefly at least:

  • This is wrong, the resultant type will always be the type returned, whether specified explicitly or not;
  • you would need to know the type anyway, if you intend to use the result! var doesn't change that;
  • this third item is pure poppycock; it makes no sense in and of itself;
  • IEnumerable generally just does represent an in-memory collection (it doesn't have to, mind, as it's only a contract for collections toi adhere to, regardless of their ultimate storage) and the idea is largely juxtaposed to the rest of this question;

A note on usage of var , though, to give a broader set of notions: using var is generally only a good idea when the resultant type is evident based on the current statement - I don't really understand Darren's reasoning or how that would ever be useful, but consider the following:

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

var is a contextual keyword that implicitly types a variable. When you use IEnumerable<T> you are explicitly stating the type to be defined, were as var will use type inference.

It doesn't really make a difference which one you use, more of a coding style IMO, I personally use var when returning something from a collection using LINQ rather than IEnumerable<T> or IQueryable<T> .

var value5 = list.Where(i => i == 5).ToList();
IEnumerable<int> value5 = list.Where(i => i == 5).ToList();

Both will generate the same output.

With regards to point 3 and 4. I don't believe that IEnumerable is any more beneficial for in memory collections at all. Behind the scenes the CLR will infer the variables type (When using var) at runtime, most likely to IEnumerable<T> .

var is just an implicitly typed local variable. You just let the compiler determine the type.

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

It is also super handy when working with anonymous types, eg.

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

More information here.

If one says 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 , and will thus exhibit *value semantics*. If the type of MyList had been IEnumerable , the return type of MyList.GetEnumerator() would have been IEnumerator`, which has reference semantics .

This difference could be important if eg one had a method which read five items from an IEnumerator<String> . If one calls such a method multiple times with a variable of type IEnumerator<String> , each call will read the next five items from the enumeration. By contrast, if one calls such a method multiple times with a value type like List<String>.Enumerator , each call will copy the enumeration state to a new heap object which implements IEnumerator<T> , pass that object to the method (which will read five items through it), and then abandon that object and its associated space (leaving the enumeration state associated with the original variable unaffected).

Note that in probably 99% of cases, either value semantics or reference semantics would be equally acceptable in an enumerator; in the majority of those, value semantics would make code run faster, and only very rarely would it make code run meaningfully slower. Further, there are some cases where knowing that an enumerator will behave as a value type could be semantically useful (eg if one wanted to be able to repeatedly re-enumerate part of a collection). On the other hand, it's probably a good idea for code which uses implementations of IEnumerator<T> to be aware of what kind of implementation they may be using.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM