[Standard]c#/.net tip: ToDictionary () and ToList ()

Source: Internet
Author: User

Preface:

There are two easy-to-use LINQ extension Methods ToDictionary () and ToList () that you may know or do not know, but it does make it possible to simplify the task of querying into collections:

Summary: LINQ and deferred execution

According to the LINQ you know, you might not know what these query expressions are doing behind the scenes. Let's talk about the purpose of our example today, we have some Poco classes (Poco represents a traditional CLR object, refers to a class, it has very few functions, this concept originates from Java POJO).

1 //just a simple product POCO class. 2   Public classProduct3  {4      Public stringName {Get;Set; }5      Public intId {Get;Set; }6      Public stringCategory {Get;Set; }7}

It's a very simple class, right? I'm not saying that the program needs to be so simple, just focus on LINQ itself, and we don't necessarily have to really query. So, in our program we can build a simple example of a collection of these objects as follows:

1 varProducts =NewList<product>2      {3          NewProduct {Name ="CD Player", Id =1, Category ="Electronics" },4          NewProduct {Name ="DVD Player", Id =2, Category ="Electronics" },5          NewProduct {Name ="Blu-ray Player", Id =3, Category ="Electronics" },6          NewProduct {Name ="LCD TV", Id =4, Category ="Electronics" },7          NewProduct {Name ="Wiper Fluid", Id =5, Category ="Automotive" },8          NewProduct {Name ="LED TV", Id =6, Category ="Electronics" },9          NewProduct {Name ="VHS Player", Id =7, Category ="Electronics" },Ten          NewProduct {Name ="Mud Flaps", Id =8, Category ="Automotive" }, One          NewProduct {Name ="Plasma TV", Id =9, Category ="Electronics" }, A          NewProduct {Name ="Washer", Id =Ten, Category ="Appliances" }, -          NewProduct {Name ="Stove", Id = One, Category ="Electronics" }, -          NewProduct {Name ="Dryer", Id = A, Category ="Electronics" }, the          NewProduct {Name ="Cup Holder", Id = -, Category ="Automotive" }, -};

That is, there are collections of objects for these products, and you need to query them. For example, we can get a collection of all product instances with the category "Electronics":

1 var " Electronics ");

Many of the query results for extension methods, including where (), create an iterator that executes the query by moving the list. Therefore, the electronicproducts is not list<product> at this time, just ienumerable<product> it will be evaluated dynamically when you use this list. This is the powerful deferred execution in LINQ, which does not evaluate an expression until you need it. At this point we can go to query electronicproducts, so we can get a list of results!

Let me see what the following results are:

1 //Select All Electronics, there is 7 of them2Ienumerable<product> electronicproducts = products. Where (p = = P.category = ="Electronics");3   4  //Now clear the original list we queried5 Products . Clear ();6   7  //Now iterate over those electronics we selected first8Console.WriteLine (Electronicproducts.count ());

Do you think the result is 7 or 0? The answer is 0, because even if we set a query on line 2nd on all the electronic products, we clear the list on line 5th. Therefore, when we actually process the query list in line 8th (execution count ()) is empty, no results are found.

If you're confused, think of it this way: creating a method that uses the LINQ Query Extension (and LINQ expression Syntax) is much like defining a stored procedure that doesn't "run" until you call it. I know it's not 100% accurate metaphor, but I hope you know that LINQ expressions are not executed in statement 2, and we handle IEnumerable.

ToList () LINQ extension method

If you want to get (store) The result of a LINQ expression immediately, you should import it into another collection so that it can be modified. Of course, you can create a list manually and populate it in a variety of ways.

1Ienumerable<product> electronicproducts = products. Where (p = = P.category = ="Electronics");2   3 //You could create a list and then hand-iterate-bulky!4  varResults =NewList<product>();5   6  foreach(varProductinchelectronicproducts)7  {8 results. ADD (product);9  }Ten    One  //OR, you could take advantage of AddRange ()-good! A  varResults2 =NewList<product>(); - results2. AddRange (electronicproducts); -    the  //OR, you could take advantage of the List ' s constructor that takes an ienumerable<t>-better! -  varResults3 =NewList<product> (electronicproducts);

In fact, using a loop is usually very verbose, or you might use the AddRange () or list<t> function to construct a ienumerable<t> list.

But you can do it in a different way. The LINQ extension method contains ToList (), and you can populate any ienumerable<t> with a list<t>. This is handy if you want to perform queries and fills in one step:

var electronicproducts = products. Where (p =  "Electronics"). ToList ();

Now, list<t> instead of Electronicproducts as the original collection for ienumerable<t> dynamic execution, this will be another new collection, and the modification will not affect the original collection.

Of course, there are pros and cons. Usually, if you just want to traverse the results and process, you don't need (and don't want to) store it in a separate list, which only wastes memory and later requires garbage collection. However, if you want to save a subset and assign it to another class, ToList () is very handy and you don't need to worry about changing the original collection.

ToDictionary () LINQ extension method

ToList () uses ienumerable<t> and converts it to List<t>, so ToDictionary () is similar. In most cases todictionary () is a convenient way to convert the results of a query (or any ienumerable<t>) into a dictionary<tkey,tvalue>. The key is that you need to define how T to convert TKey and TValue separately.

If we have a super big product list and want to put it in a dictionary<int, product>, so that we can get the fastest search time based on the ID. You might do this:

1  var New dictionary<int, product>(); 2  foreach (var in products ) 3 {4     results. ADD (product. Id, product); 5  }

And it looks like a good code, but we can easily use LINQ without having to write a lot of logic:

1 var results = products. ToDictionary (Product =  product. ID);

It constructs a dictionary<int, product>, key is the product's ID attribute, and value is the product itself. This is the simplest form of todictionary (), you only need to specify a key selector. What if you want something different as your value? For example, if you don't care about the whole product, you just want to be able to convert the ID to name? We can do this:

1 var results = products. ToDictionary (Product =  product. Id, Product =  product. Name);

This will create a key of Id,value for name Dictionary<int, String> This extension method has many ways to handle the Ienumerable<t> collection or query results to generate a dictionary.

Note: There is also a lookup<tkey, Tvalue> class, and tolookup () extension method that can do this in a similar way. They are not exactly the same solution (dictionary and lookup interfaces differ, their behavior is different when the index is not found).

So, in our product example, suppose we want to create a dictionary<string, list<product>>, key is a category, and value is a list of all products. In the past you may self-implement your own loops:

1 //Create your dictionary to hold results2  varResults =Newdictionary<string, list<product>>();3   4 //Iterate through products5  foreach(varProductinchProducts )6 {7List<product>sublist;8  9     //If the category is not in there, create a new list and add to dictionaryTen      if(!results. TryGetValue (product. Category, outsublist)) One     { ASublist =NewList<product>(); - results. ADD (product. Category, sublist); -     } the    -      //Add the product to the new (or existing) sub-list - Sublist.add (product); -}

But the code should be simpler! Any newcomer looking at this piece of code may need to go into a detailed analysis to fully understand it, which poses difficulties for maintenance

Fortunately for us, we can leverage the LINQ extension Method GroupBy () to advance todictionary () and ToList ():

// One line of code! var results = products. GroupBy (Product =  =  Group. Key, group =  Group. ToList ());

GroupBy () is a LINQ expression query statement that creates a igrouping with key and IEnumerable. So once we use GroupBy (), all we have to do is convert these groups into dictionary, so our key selector (group = group). Key) to make it a dictionary key and value selector (group = group. ToList ()) project and convert it to a list<product> as our dictionary value!

This makes it easier to read and write, and less code for unit tests! I know a lot of people would say that lamda expressions are more difficult to read, but they are part of the C # language and must be understood by senior developers. I think you will find that when you use them more and more, the code can be better understood and more readable than before.

Translator by: I use transmate translation at the same time, also try to keep the original description, to avoid the loss of information, if this article for you have a little use, please do not stingy point recommendation, let more people see, thank you!

[Standard]c#/.net tip: ToDictionary () and ToList ()

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.