How is ThenBy implemented in C #?

Source: Internet
Author: User

C # provides a wide range of extension methods for objects inherited from IEnumerable (List is the most well known), involving all aspects of List operations. The Extension Method ThenBy is an interesting one, and its implementation is also clever. If there is such a Team class, there are three attributes. Team. cs public class Team {public Team (string name, int timeCost, int score) {this. name = name; this. timeCost = timeCost; this. score = score;} public string Name {get; private set;} public int TimeCost {get; private set;} public int Score {get; private set ;}} then we have a List of teams. List <Team> teams = new List <Team> (); teams. add (new Team ("teamA", 10, 22); teams. add (new Team ("teamB", 12, 20); teams. add (new Team ("teamC", 8, 18); how can we find the Team with the highest score in teams? This is very simple. You only need one sentence. Var result = teams. orderByDescending (team => team. score ). first (); Console. writeLine (result. name); // teamA because List implements the IEnumerable interface, and System. the Enumerable class in Linq contains an extension method named OrderByDescending for the IEnumerable interface. Therefore, we can directly call this extension method to sort the List in descending order according to the specified key, call the First extension method to obtain the First element in the list. If my List is like this. List <Team> teams = new List <Team> (); teams. add (new Team ("teamA", 10, 18); teams. add (new Team ("teamB", 12, 16); teams. add (new Team ("teamC", 8, 18); because it is possible that more than two groups of teams may receive the highest score, among these teams, we select the least-used winner as the final winner. Some people say it can be written like this. Var result = teams. orderByDescending (team => team. score ). orderBy (team => team. timeCost ). first (); First sort the list by Score in descending order, then sort the list by TimeCost in ascending order, and then take the First element in the result. It seems to be correct, but it is actually wrong. Because the first time the OrderByDescending method is called, an array after sorting is returned, and then the OrderBy method is called for another sorting, it will discard the last sorting, which is consistent with the point first, if the points are the same, then the time-consuming rules are violated. So how should we implement it? C # provides us with a ThenBy method that can meet our requirements. Var result = teams. orderByDescending (team => team. score ). thenBy (team => team. timeCost ). first (); Console. writeLine (result. name); // a new problem with teamC is coming. When the OrderByDescending method is called for the first time, a new object is returned. When ThenBy is called for this new object, it only records the last sorting rule to achieve the desired effect. So how does C # record the key used in the last sorting? This depends on how the OrderByDescending method is implemented. Check the source code and find that OrderByDescending has two overloading methods. The implementation is as follows. Public static IOrderedEnumerable <TSource> OrderByDescending <TSource, TKey> (this IEnumerable <TSource> source, Func <TSource, TKey> keySelector) {return source. orderByDescending (keySelector, null);} public static IOrderedEnumerable <TSource> OrderByDescending <TSource, TKey> (this IEnumerable <TSource> source, Func <TSource, TKey> keySelector, IComparer <TKey> comparer) {Check. sourceAndKeySelector (sour Ce, keySelector); return new OrderedSequence <TSource, TKey> (source, keySelector, comparer, SortDirection. descending);} in the second overload, we can see that the OrderByDescending method returns an object OrderedSequence that inherits the IOrderedEnumerable interface. This object records our sorting rules. Let's look at the definition of the ThenBy method. Public static IOrderedEnumerable <TSource> ThenBy <TSource, TKey> (this IOrderedEnumerable <TSource> source, Func <TSource, TKey> keySelector, IComparer <TKey> comparer) {Check. sourceAndKeySelector (source, keySelector); return source. createOrderedEnumerable <TKey> (keySelector, comparer, false);} public static IOrderedEnumerable <TSource> ThenBy <TSource, TKey> (this IOrderedEnumerable <TSource> source, F Unc <TSource, TKey> keySelector) {return source. thenBy (keySelector, null);} we can see that the object type appended to the ThenBy extension method must implement the IOrderedEnumerable interface, and the OrderBy method just returns the interface object of this type. Then let's look at the definition of the IOrderedEnumerable interface. Using System; using System. collections; using System. collections. generic; namespace System. linq {public interface IOrderedEnumerable <TElement>: IEnumerable <TElement>, IEnumerable {// Methods <TElement> CreateOrderedEnumerable <TKey> (Func <TElement, TKey> keySelector, IComparer <TKey> comparer, bool descending) ;}}it inherits from the IEnumerable interface and implements a method named CreateOrderedEnumerable, Which is exactly ThenBy The method called in the method implementation.

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.