{"id":94710,"date":"2023-08-07T05:44:44","date_gmt":"2023-08-07T03:44:44","guid":{"rendered":"https:\/\/code-maze.com\/?p=94710"},"modified":"2023-08-07T05:44:44","modified_gmt":"2023-08-07T03:44:44","slug":"csharp-techniques-for-sorting-list","status":"publish","type":"post","link":"https:\/\/code-maze.com\/csharp-techniques-for-sorting-list\/","title":{"rendered":"Techniques for Sorting a List in C#"},"content":{"rendered":"<p>In this article, we will explore different techniques for sorting a list. A common task we face as developers is the need to sort a collection of data. The C# language provides us with a variety of ways in which we can accomplish this task. To help us have a better understanding of the available options, we will walk through several examples together.\u00a0<\/p>\n<p>Along with exploring different techniques for sorting a list, we will also implement our own custom <code>MySortedList<\/code> class which will allow us to maintain a list of data in a sorted fashion.<\/p>\n<p>With that in mind, let&#8217;s dive into some code.<\/p>\n<div style=\"padding: 20px; border-left: 5px #dc2323 solid; display: block; margin-bottom: 20px; box-shadow: 1px 1px 5px 0px lightgrey;\">To download the source code for this article, you can visit our <a href=\"https:\/\/github.com\/CodeMazeBlog\/CodeMazeGuides\/tree\/main\/collections-lists\/SortingGenericList\/\" target=\"_blank\" rel=\"nofollow noopener\">GitHub repository<\/a>.<\/div>\n<h2>Setting Up Our Example Code<\/h2>\n<p>First, let&#8217;s create a simple <code>record<\/code> that we can use to explore the different options and techniques for sorting a list:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">public sealed record Product(string ProductName, string Category, decimal Price)\r\n{\r\n    public Guid Id { get; init; } = Guid.NewGuid();\r\n}<\/pre>\n<p>Second, let&#8217;s generate some sample data, which we can use to demonstrate the different techniques for sorting a list:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">new Product?[]\r\n{\r\n    new(\"Gorgeous Fish\", \"Games\", 103.07m) { Id = Guid.Parse(\"f0569e86-bfad-6f3a-b74d-2555175dcc6e\") },\r\n    new(\"Tasty Cheese\", \"Clothing\", 134.74m) { Id = Guid.Parse(\"4af80b60-3e17-1dfd-8462-c009ca918154\") },\r\n    null,\r\n    new(\"Handcrafted Hat\", \"Books\", 38.09m) { Id = Guid.Parse(\"c7b30b28-db07-f2ae-70dc-9505096e676b\") },\r\n    new(\"Practical Chicken\", \"Electronics\", 126.06m) { Id = Guid.Parse(\"d6fee4b9-8767-851a-b386-a8af727663a7\") },\r\n    new(\"Generic Car\", \"Games\", 75.18m) { Id = Guid.Parse(\"c65100fd-e49f-f5e0-0e71-052d7eefe9b3\") }\r\n};\r\n<\/pre>\n<p>As a side note, we have generated this data using the <code>Bogus<\/code> NuGet package. To learn more about <strong>Bogus<\/strong> and how it can be used to generate &#8220;realistic&#8221; testing data, be sure to check out <a href=\"https:\/\/code-maze.com\/data-generation-bogus-dotnet\/\" target=\"_blank\" rel=\"noopener\">our article<\/a> on the topic.<\/p>\n<p>Formatted nicely, our unsorted data looks like this:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\">Gorgeous Fish                 Games               $103.07        f0569e86-bfad-6f3a-b74d-2555175dcc6e\r\nTasty Cheese                  Clothing            $134.74        4af80b60-3e17-1dfd-8462-c009ca918154\r\nNULL                          NULL                $0.00          00000000-0000-0000-0000-000000000000\r\nHandcrafted Hat               Books               $38.09         c7b30b28-db07-f2ae-70dc-9505096e676b\r\nPractical Chicken             Electronics         $126.06        d6fee4b9-8767-851a-b386-a8af727663a7\r\nGeneric Car                   Games               $75.18         c65100fd-e49f-f5e0-0e71-052d7eefe9b3<\/pre>\n<p>So let&#8217;s dive in and begin exploring the different options available to us for sorting.<\/p>\n<h2>IComparable&lt;T&gt; Interface for Sorting a List in C#<\/h2>\n<p>The <code>IComparable&lt;T&gt;<\/code> interface provides a mechanism for defining the default comparison behavior of a class. When defining a new class, that we wish to be sortable, we implement this interface to define the default sorting order.<\/p>\n<p>The <code>IComparable&lt;T&gt;<\/code> interface defines a single method that we need to implement:<\/p>\n<p><code class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">public int CompareTo (T? other)<\/code><\/p>\n<p>The value returned indicates the relative positioning of the two objects within the desired sort order:<\/p>\n<ul>\n<li><code>&lt; 0<\/code> &#8211; the instance precedes <code>other<\/code> in the sort order<\/li>\n<li><code>0<\/code> &#8211; the instance is in the same position as <code>other<\/code> in the sort order<\/li>\n<li><code>&gt; 0<\/code> &#8211; the instance follows <code>other<\/code> in the sort order<\/li>\n<\/ul>\n<p>When implementing <code>IComparable&lt;T&gt;<\/code> <strong>we should also override<\/strong> <code>Equals()<\/code> as well as the comparison operators <code>&lt;<\/code>, <code>&lt;=<\/code>, <code>&gt;<\/code>, <code>&gt;=<\/code>\u00a0to maintain consistency with the results of <code>CompareTo()<\/code>. When overriding <code>Equals()<\/code> it is good practice to also override the <strong>equality<\/strong> and <strong>inequality<\/strong> operators <code>==<\/code> and <code>!=<\/code>.<\/p>\n<p>For more information concerning <strong>overriding<\/strong> <code>Equals()<\/code> and <strong>operator overloading, <\/strong>you can <a href=\"https:\/\/code-maze.com\/csharp-operator-overloading\/\" target=\"_blank\" rel=\"noopener\">check out our article<\/a> covering that topic.\u00a0<\/p>\n<p>For simplicity&#8217;s sake and to keep the focus of our article on sorting, we are using a <code>record<\/code> rather than a class, which handles the equality overriding for us. You can read more about the <code>record<\/code> type in our article <a href=\"https:\/\/code-maze.com\/csharp-records\/\" target=\"_blank\" rel=\"noopener\">here<\/a>.\u00a0<\/p>\n<h3>Implementing IComparable&lt;T&gt;<\/h3>\n<p>Now, let&#8217;s take a look at implementing the <code>IComparable&lt;T&gt;<\/code> interface on our <code>Product<\/code> record. First, we will change our record signature to include the <code>IComparable&lt;T&gt;<\/code> interface, along with the non-generic <code>IComparable<\/code> interface:<\/p>\n<p><code class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">public sealed record Product(string ProductName, string Category, decimal Price) : IComparable&lt;Product&gt;, IComparable<\/code><\/p>\n<p>First, let&#8217;s take a look at our <code>IComparable&lt;Product&gt;<\/code> implementation. We will focus on sorting <code>Products<\/code>based primarily on the <code>ProductName<\/code> and only secondarily sort based on the <code>Price<\/code>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">public int CompareTo(Product? other)\r\n{\r\n    if (ReferenceEquals(this, other)) return 0;\r\n    if (other is null) return 1;\r\n\r\n    var nameComparison = string.Compare(ProductName, other.ProductName,\r\n        StringComparison.OrdinalIgnoreCase);\r\n\r\n    return nameComparison != 0 ? nameComparison : Price.CompareTo(other.Price);\r\n}<\/pre>\n<p>The first thing we do on line #3 is to perform a reference comparison to check if we are comparing the same object with itself. If that is the case, we return <code>0<\/code>, indicating that the objects occur in the same position within the sort order. <strong>Note<\/strong> that we did not say that a return value of <code>0<\/code> indicates equality, only their relative positioning within the sort order. Equal objects must return <code>0<\/code>, but it is possible, based on how we are sorting, to have two unequal objects that still share the same position in relation to their sort order.<\/p>\n<p>Second, on line #4 we check whether <code>other<\/code> is <code>null<\/code>. In the case of it being <code>null<\/code>, we return <code>1<\/code> indicating that our current object is larger than the <code>null<\/code> object.<\/p>\n<p>Third, on line #6 we compare the <code>ProductName<\/code> of the two objects. Since we have already verified that they are not the same object and that <code>other<\/code> is not null, we can safely make this comparison.<\/p>\n<p>This leads us to the last line, #8, where we check to see if the <code>ProductName<\/code> has the same sort-order positioning. If it does, then we compare the <code>Price<\/code> as a way of determining which object should be first in the sort order.<\/p>\n<h3>IComparable&lt;T&gt; Implementation In Action<\/h3>\n<p>Now let&#8217;s see what happens when we sort our <code>Product<\/code> collection:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">var productList = new List&lt;Product?&gt;(products);\r\nproductList.Sort();<\/pre>\n<p>Let&#8217;s inspect the result:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\">NULL                          NULL                $0.00          00000000-0000-0000-0000-000000000000\r\nGeneric Car                   Games               $75.18         c65100fd-e49f-f5e0-0e71-052d7eefe9b3\r\nGorgeous Fish                 Games               $103.07        f0569e86-bfad-6f3a-b74d-2555175dcc6e\r\nHandcrafted Hat               Books               $38.09         c7b30b28-db07-f2ae-70dc-9505096e676b\r\nPractical Chicken             Electronics         $126.06        d6fee4b9-8767-851a-b386-a8af727663a7\r\nTasty Cheese                  Clothing            $134.74        4af80b60-3e17-1dfd-8462-c009ca918154<\/pre>\n<h2>IComparer&lt;T&gt; Interface for Sorting a List in C#<\/h2>\n<p>Sometimes when we are sorting, we do not want to follow the default sort defined for a given type <code>T<\/code>. The <code>IComparer&lt;T&gt;<\/code> interface is one of the techniques we can use for sorting a list according to our own desired sort order. It allows an implementing type to define a <code>Compare()<\/code> method that can be used to sort objects of type <code>T<\/code>. The <code>Compare()<\/code> method signature is very similar to the <code>CompareTo()<\/code> method that we looked at with the <code>IComparable&lt;T&gt;<\/code> interface:<\/p>\n<p><code class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">public int Compare (T? a, T? b)<\/code><\/p>\n<p>Just like the <code>CompareTo()<\/code> method, the value returned indicates the relative positioning of the two objects within the desired sort order:<\/p>\n<ul>\n<li><code>&lt; 0<\/code> &#8211; <code>a<\/code> precedes <code>b<\/code> in the sort order<\/li>\n<li><code>0<\/code> &#8211; <code>a<\/code> is in the same position as <code>b<\/code> in the sort order<\/li>\n<li><code>&gt; 0<\/code> &#8211; <code>a<\/code> follows <code>b<\/code> in the sort order<\/li>\n<\/ul>\n<p>A common use case for the <code>IComparer&lt;T&gt;<\/code> is to define a custom comparer to use for sorting a collection differently than the default ordering defined by the object. For example, the default sort ordering of our <code>Product<\/code> object is based on the natural ordering of the <code>ProductName<\/code>. We can override that behavior when sorting a collection by defining an <code>IComparer&lt;Product&gt;<\/code> that sorts based on the price.<\/p>\n<h3>Implementing IComparer&lt;T&gt; for Custom Sorting<\/h3>\n<p>Let&#8217;s take a look at it in action. We&#8217;ll start with our class definition:<\/p>\n<p><code class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">public sealed class ProductPriceIComparer : IComparer&lt;Product?&gt;<\/code><\/p>\n<p>The only thing left to do is to implement the <code>Compare(Product? x, Product? y)<\/code> method:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">public int Compare(Product? a, Product? b)\r\n{\r\n    if (ReferenceEquals(a, b)) return 0;\r\n    if (a is null) return -1;\r\n    if (b is null) return 1;\r\n\r\n    var priceComparison = a.Price.CompareTo(b.Price);\r\n\r\n    return priceComparison != 0 ? priceComparison :\r\n        string.Compare(a.ProductName, b.ProductName, StringComparison.OrdinalIgnoreCase);\r\n}<\/pre>\n<p>The code looks very similar to the <code>CompareTo()<\/code> method that we defined earlier, with one very notable difference, the number of arguments. <code>CompareTo()<\/code> is a member of the <code>Product<\/code> class and so only takes a single argument, namely the other <code>Product<\/code> to compare with the current <code>Product<\/code>. When we implement the <code>ICompare&lt;T&gt;<\/code> interface, the <code>Compare()<\/code> method performs the comparison with two provided <code>Product<\/code> objects.\u00a0<\/p>\n<p>First, on line #3, we check whether the two objects are the same object. In that case, we just return <code>0<\/code>. Next, on line #4, we check to see if <code>a<\/code> is <code>null<\/code>. If it is, then we return <code>-1<\/code> indicating that <code>a<\/code> comes before <code>b<\/code> in the sorting order. On line #5 we also check whether <code>b<\/code> is <code>null<\/code> and if it is, we return <code>1<\/code> to indicate that <code>b<\/code> comes before <code>a<\/code> in the sorting order.<\/p>\n<p>The major difference between our earlier <code>CompareTo()<\/code> and this <code>Compare()<\/code> is found on lines 7 and 9. In our <code>CompareTo()<\/code> method, we first performed a comparison on the <code>ProductName<\/code> and then, only if the <code>ProductName<\/code> was equal regarding sort order, did we compare the <code>Price<\/code>. In this case, we are checking the <code>Price<\/code> first, as our goal is to order <code>Products<\/code> according to <code>Price<\/code> rather than <code>ProductName<\/code>.\u00a0<\/p>\n<h3>IComparer&lt;T&gt; Implementation in Action<\/h3>\n<p>Let&#8217;s see our collection when we sort it using the <code>ProductPriceIComparer<\/code>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">var productList = new List&lt;Product?&gt;(products);\r\nproductList.Sort(new ProductPriceIComparer());<\/pre>\n<p>And, let&#8217;s check the result:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\">NULL                          NULL                $0.00          00000000-0000-0000-0000-000000000000\r\nHandcrafted Hat               Books               $38.09         c7b30b28-db07-f2ae-70dc-9505096e676b\r\nGeneric Car                   Games               $75.18         c65100fd-e49f-f5e0-0e71-052d7eefe9b3\r\nGorgeous Fish                 Games               $103.07        f0569e86-bfad-6f3a-b74d-2555175dcc6e\r\nPractical Chicken             Electronics         $126.06        d6fee4b9-8767-851a-b386-a8af727663a7\r\nTasty Cheese                  Clothing            $134.74        4af80b60-3e17-1dfd-8462-c009ca918154<\/pre>\n<h2>The Comparer&lt;T&gt; Abstract Class<\/h2>\n<p>We have already looked at the <code>IComparer&lt;T&gt;<\/code> interface, so now let&#8217;s take a look at the abstract class <code>Comparer&lt;T&gt;<\/code> which is an abstract base class that implements the <code>IComparer&lt;T&gt;<\/code> interface.<\/p>\n<p>Given the choice between implementing the interface and deriving from the base class, <strong>deriving from <code>Comparer&lt;T&gt;<\/code> is the recommended approach by Microsoft<\/strong>. The <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/system.collections.generic.icomparer-1?view=net-7.0#remarks\" target=\"_blank\" rel=\"nofollow noopener\">remarks<\/a> section of the documentation for <code>IComparer&lt;T&gt;<\/code> explains why we should prefer deriving from <code>Comparer&lt;T&gt;<\/code> over implementing the interface.<\/p>\n<h3>Deriving from Comparer&lt;T&gt;<\/h3>\n<p>So let&#8217;s take a look at creating a custom comparer to sort our <code>Product<\/code> items by <code>Id<\/code> via the <code>Comparer&lt;T&gt;<\/code>:<\/p>\n<p><code class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">public sealed class ProductIdComparer : Comparer&lt;Product?&gt;<\/code><\/p>\n<p>Since we are looking to implement a comparer for the <code>Product<\/code> class, we derive from the generic <code>Comparer&lt;T&gt;<\/code> class passing in <code>Product<\/code> for our generic type argument.<\/p>\n<p>Next, we need to implement <code>Compare()<\/code>, just like we did when implementing the <code>IComparer&lt;T&gt;<\/code> interface:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">public override int Compare(Product? a, Product? b)\r\n{\r\n    \/\/ removed for brevity\r\n    return a.Id.CompareTo(b.Id);\r\n}<\/pre>\n<p>For brevity, we have omitted the first three lines of the method, as they are identical to lines 3-5 in the <code>IComparer&lt;T&gt;<\/code> implementation. In our case, we are defining a comparison based on the <code>Id<\/code> of the <code>Product<\/code>. With this as our goal, all we need to do is return the result of the <code>Id<\/code> comparison.<\/p>\n<p>One <strong>important<\/strong> difference to note between implementing the <code>IComparer&lt;T&gt;<\/code> interface and deriving from <code>Comparer&lt;T&gt;<\/code> is the signature of the <code>Compare()<\/code> method. When implementing the interface, we simply define a public <code>Compare()<\/code> method. When deriving from the base class, we have to <strong>override<\/strong> the <code>Compare()<\/code> method.<\/p>\n<h3>Comparer&lt;T&gt; Implementation in Action<\/h3>\n<p>Let&#8217;s take a look at our <code>Id<\/code> comparer in action:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">var productList = new List&lt;Product?&gt;(products);\r\nproductList.Sort(new ProductIdComparer());<\/pre>\n<p>The result:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\">NULL                          NULL                $0.00          00000000-0000-0000-0000-000000000000\r\nTasty Cheese                  Clothing            $134.74        4af80b60-3e17-1dfd-8462-c009ca918154\r\nGeneric Car                   Games               $75.18         c65100fd-e49f-f5e0-0e71-052d7eefe9b3\r\nHandcrafted Hat               Books               $38.09         c7b30b28-db07-f2ae-70dc-9505096e676b\r\nPractical Chicken             Electronics         $126.06        d6fee4b9-8767-851a-b386-a8af727663a7\r\nGorgeous Fish                 Games               $103.07        f0569e86-bfad-6f3a-b74d-2555175dcc6e<\/pre>\n<h2>Sorting With The Comparison&lt;T&gt; Delegate<\/h2>\n<p>Now, let&#8217;s take a look at the <code>Comparison&lt;T&gt;<\/code> delegate. This delegate is one of the techniques we can employ when sorting a list. The following signature defines it:<\/p>\n<p><code class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">public delegate int Comparison&lt;in T&gt;(T a, T b);<\/code><\/p>\n<p>Just like our other comparison methods (<code>CompareTo()<\/code> and <code>Compare()<\/code>), the <code>Comparison&lt;T&gt;<\/code> delegate returns an <code>int<\/code> based on the sort order of compared objects:<\/p>\n<ul>\n<li><code>&lt; 0<\/code> &#8211; <code>a<\/code> precedes <code>b<\/code> in the sort order<\/li>\n<li><code>0<\/code> &#8211; <code>a<\/code> is in the same position as <code>b<\/code> in the sort order<\/li>\n<li><code>&gt; 0<\/code> &#8211; <code>a<\/code> follows <code>b<\/code> in the sort order<\/li>\n<\/ul>\n<p>To use the <code>Comparison&lt;T&gt;<\/code> delegate, we simply invoke the <code>Sort()<\/code> overload that accepts the delegate. We can accomplish this either by passing in a lambda function directly or by defining a method that matches the delegate signature. Let&#8217;s look at both options.<\/p>\n<h3>Defining Comparison&lt;T&gt; Delegate via a Lambda<\/h3>\n<p>Here we&#8217;ll invoke <code>Sort()<\/code> with a lambda that orders our <code>Product<\/code> items by <code>Category<\/code>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">var productList = new List&lt;Product?&gt;(products);\r\nproductList.Sort((a, b) =&gt;\r\n{\r\n    \/\/ object and null checks removed for brevity\r\n    var result = string.Compare(a.Category, b.Category, StringComparison.OrdinalIgnoreCase);\r\n\r\n    return result != 0 ? result : a.CompareTo(b);\r\n});<\/pre>\n<p>Once again for brevity, we removed the object and null checks from the code listing, as they are identical to our earlier example. Following those checks, we perform a comparison of the <code>Category<\/code> property. If the <code>Product<\/code> instance <code>a<\/code> and <code>b<\/code> compare share the same category, we fall back to calling the default comparison (<code>Name<\/code>, followed by <code>Price<\/code>).<\/p>\n<p>Now let&#8217;s take a look at the result:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\">NULL                          NULL                $0.00          00000000-0000-0000-0000-000000000000\r\nHandcrafted Hat               Books               $38.09         c7b30b28-db07-f2ae-70dc-9505096e676b\r\nTasty Cheese                  Clothing            $134.74        4af80b60-3e17-1dfd-8462-c009ca918154\r\nPractical Chicken             Electronics         $126.06        d6fee4b9-8767-851a-b386-a8af727663a7\r\nGeneric Car                   Games               $75.18         c65100fd-e49f-f5e0-0e71-052d7eefe9b3\r\nGorgeous Fish                 Games               $103.07        f0569e86-bfad-6f3a-b74d-2555175dcc6e<\/pre>\n<h3>Defining Comparison&lt;T&gt; Delegate via a Method<\/h3>\n<p>As we mentioned earlier, we can also define a method that matches the <code>Comparison&lt;T&gt;<\/code> delegate signature and pass that as the argument to the <code>Sort()<\/code> overload, which takes a <code>Comparison&lt;T&gt;<\/code>. Let&#8217;s see how this works by defining a new static <code>DescendingCompare()<\/code> method in our <code>Product<\/code> class:<\/p>\n<p><code class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">public static int DescendingCompare(Product? a, Product? b) =&gt; b?.CompareTo(a) ?? -1;<\/code><\/p>\n<p>This method is pretty straightforward. Our goal is to sort <code>Products<\/code> in descending order, so all we need to do is &#8220;reverse&#8221; the comparison result of the current <code>CompareTo()<\/code> implementation. We accomplish this by reversing the operands when performing the comparison. That is, instead of comparing <code>a<\/code> to <code>b<\/code>, we compare <code>b<\/code> to <code>a<\/code>. One thing to <strong>note<\/strong> is the return value when <code>b<\/code> is <code>null<\/code>. Because we are sorting in <strong>descending<\/strong> order, smaller values sort lower in the collection, and therefore if <code>b<\/code> is <code>null<\/code> we return <code>-1<\/code>.<\/p>\n<p>Now let&#8217;s put it to use:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">var productList = new List&lt;Product?&gt;(products);\r\nproductList.Sort(Product.DescendingCompare);<\/pre>\n<p>And the results:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\">Tasty Cheese                  Clothing            $134.74        4af80b60-3e17-1dfd-8462-c009ca918154\r\nPractical Chicken             Electronics         $126.06        d6fee4b9-8767-851a-b386-a8af727663a7\r\nHandcrafted Hat               Books               $38.09         c7b30b28-db07-f2ae-70dc-9505096e676b\r\nGorgeous Fish                 Games               $103.07        f0569e86-bfad-6f3a-b74d-2555175dcc6e\r\nGeneric Car                   Games               $75.18         c65100fd-e49f-f5e0-0e71-052d7eefe9b3\r\nNULL                          NULL                $0.00          00000000-0000-0000-0000-000000000000<\/pre>\n<h2>Constraining the Sorting to a Range<\/h2>\n<p>Regarding techniques for sorting a list using the <code>List.Sort()<\/code> method, there is one additional overload that we haven&#8217;t discussed yet. This overload allows us to restrict our sorting to a specific range within the list. The method signature is as follows:<\/p>\n<p><code class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">List&lt;T&gt;.Sort(int index, int count, IComparer&lt;T&gt;? comparer)<\/code><\/p>\n<p>We specify the starting <code>index<\/code> via the first parameter. The second parameter specifies the number of elements that should be included in the sort, starting from the <code>index<\/code>. The last parameter, which may be <code>null<\/code>, specifies the <code>IComparer&lt;T&gt;<\/code> to use for performing the sort. If we pass in <code>null<\/code>, then the default comparer for type <code>T<\/code> will be used.<\/p>\n<p>As expected, the range we specify must be valid for the list. If we try to pass in negatives or a range that does not fall within the bounds of the list, an <code>ArgumentException<\/code> will be thrown. Also, if we specify <code>null<\/code> for the <code>comparer<\/code>, and <code>T<\/code> does not have a default comparer defined, then an <code>InvalidOperationException<\/code> will be thrown.\u00a0<\/p>\n<p>Now, let&#8217;s see this overload of <code>Sort()<\/code> in action. We will sort the first 3 elements of our sample list by <code>Price<\/code>, which is handled by our previous implementation <code>ProductPriceIComparer<\/code>, and the last 3 using the default <code>Product<\/code> comparison:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">var productList = new List&lt;Product?&gt;(products);\r\nproductList.Sort(0, 3, new ProductPriceIComparer());\r\nproductList.Sort(3, 3, null);<\/pre>\n<p>And the results:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\">NULL                          NULL                $0.00          00000000-0000-0000-0000-000000000000\r\nGorgeous Fish                 Games               $103.07        f0569e86-bfad-6f3a-b74d-2555175dcc6e\r\nTasty Cheese                  Clothing            $134.74        4af80b60-3e17-1dfd-8462-c009ca918154\r\nGeneric Car                   Games               $75.18         c65100fd-e49f-f5e0-0e71-052d7eefe9b3\r\nHandcrafted Hat               Books               $38.09         c7b30b28-db07-f2ae-70dc-9505096e676b\r\nPractical Chicken             Electronics         $126.06        d6fee4b9-8767-851a-b386-a8af727663a7<\/pre>\n<h2>Custom MySortedList&lt;T&gt; Implementation for Sorting<\/h2>\n<p>The previous examples all focused on techniques for sorting a list in place. Another option we can consider is to maintain our <code>List<\/code> in sorted order. The <code>List<\/code> class contains a method <code>BinarySearch()<\/code> that enables us to achieve this goal. To make dealing with the behavior a bit clearer, we will create a custom <code>MySortedList&lt;T&gt;<\/code> class, which under the hood, will still use <code>List&lt;T&gt;<\/code>, but will maintain it in a sorted state. For brevity, we will not explore the entire class here.<\/p>\n<h3>Class Definition for Custom Sorting<\/h3>\n<p>First, let&#8217;s take a look at our class definition:<\/p>\n<p><code class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">public sealed class MySortedList&lt;T&gt; : IList&lt;T&gt; where T : IComparable&lt;T&gt;<\/code><\/p>\n<p>Because our goal is to maintain the sort order of our collection, we are restricting our type parameter <code>T<\/code> to those that implement <code>IComparable&lt;T&gt;<\/code>. Since we are creating a special type of list, we will also implement the <code>IList&lt;T&gt;<\/code> interface, so that we can use our sorted list in most places where we would use a standard <code>List&lt;T&gt;<\/code>.<\/p>\n<p>Having said that, the fact that this list will always maintain a sorted order does add a couple of restrictions regarding the <code>IList&lt;T&gt;<\/code> interface. Namely, there are a couple of methods in the interface that we will not implement, but rather throw a <code>NotSupportedException<\/code>.<\/p>\n<p>The first one is the <code>Insert(int index, T item)<\/code> method. Since our requirement is that our list is always sorted, we cannot support inserting at a specific index. Secondly, and related to the insert issue, is allowing <code>set()<\/code> through the indexer <code>[]<\/code>. Retrieving a value at a given index is fully supported, but we cannot support setting the value, as that could lead to the list becoming unsorted.<\/p>\n<h3>Constructor Definitions<\/h3>\n<p>Just like <code>List<\/code>, we allow setting the initial capacity of the list through the constructor. Because we are maintaining the list in sorted order, we also allow for passing in a custom <code>ICompare&lt;T&gt;<\/code> which, if provided, will be used to define the sort order:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">public MySortedList(int capacity = 0, IComparer&lt;T&gt;? comparer = null)\r\n{\r\n    _list = new List&lt;T&gt;(capacity);\r\n    _comparer = comparer;\r\n}<\/pre>\n<p>Not shown are the class member variables for <code>_list<\/code> and <code>_comparer<\/code>, but from the constructor, we see that <code>_list<\/code> is our internal <code>List&lt;T&gt;<\/code> and <code>_comparer<\/code> is the <code>IComparer&lt;T&gt;<\/code> that we will use if it is provided.<\/p>\n<p>For ease of use and to mirror <code>List&lt;T&gt;<\/code> we will also provide a constructor which takes an <code>IEnumerable&lt;T&gt;<\/code>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">public MySortedList(IEnumerable&lt;T&gt; initialValues, IComparer&lt;T&gt;? comparer = null) : this(comparer: comparer)\r\n    =&gt; AddRange(initialValues);<\/pre>\n<p>With this constructor, we chain into our earlier constructor and then we pass the\u00a0<code>initialValues<\/code> into our <code>AddRange()<\/code> function.<\/p>\n<h3>Adding Elements to Our Custom List Implementation<\/h3>\n<p>Our <code>Add()<\/code> method is where our new friend <code>BinarySearch()<\/code> really shines. As the name suggests, it searches through a <strong>sorted collection<\/strong> using a binary search strategy. Upon finding a matching element, it returns its index. When the element is not found, it returns a negative number that is the bitwise complement of the index of the next larger element. This means that by taking the complement, we get the insertion index for this item. Let&#8217;s take a look at our <code>Add()<\/code> method:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">public void Add(T item)\r\n{\r\n    var index = _list.BinarySearch(item, _comparer);\r\n    if (index &lt; 0) index = ~index;\r\n\r\n    _list.Insert(index, item);\r\n}<\/pre>\n<p>On line #3 we see that the first thing we do, when adding, is to search for a matching item using <code>BinarySearch()<\/code>. The next step is to check whether the returned index is negative or not. As we mentioned earlier, in the case of a negative value (item not found), by taking the complement, we get our insertion index. The last step, line #6, is to perform the actual insertion. Since we are allowing duplicate items in our list, we simply insert the item at the computed index. We insert the new item in the list if we find a matching item. If no item was found, we insert the new item at the location computed by the complement of the <code>BinarySearch()<\/code> result.<\/p>\n<p>It will probably be clearer to understand this by walking through a simple example.<\/p>\n<h3>Using BinarySearch to Maintain Sort Order When Inserting<\/h3>\n<p>Let&#8217;s say we have the array of integers that we wish to insert into our custom <code>MySortedList<\/code>:<\/p>\n<p><code class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">var data = new int[] {5, 1, 5, 3};<\/code><\/p>\n<p>Now let&#8217;s loop through them, adding each one to our sorted list:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">var sortedList = new MySortedList&lt;int&gt;();\r\nforeach(var num in data) sortedList.Add(num);<\/pre>\n<p>The first time through the loop (<code>5<\/code>), the internal list is empty, so when we get to line #3 in the <code>Add()<\/code> method, <code>BinarySearch()<\/code> will return <code>-1<\/code>. Taking the complement, we get <code>0<\/code>, and so we insert our element at index <code>0<\/code>. And after the first iteration of the loop our list now looks like this: <code>{5}<\/code><\/p>\n<p>On our second iteration (<code>1<\/code>), <code>BinarySearch()<\/code> once again returns <code>-1<\/code> as the item does not exist, and belongs at the beginning of the list (complement of <code>-1<\/code> being <code>0<\/code>). Now, our list looks like this: <code>{1, 5}<\/code>.<\/p>\n<p>On our third iteration (<code>5<\/code>), <code>BinarySearch()<\/code> returns <code>1<\/code> as expected, since <code>5<\/code> already exists in our list. We insert the new item at the found index, and now have the following list: <code>{1, 5, 5}<\/code>.<\/p>\n<p>Our fourth iteration (<code>3<\/code>), is where it gets a bit more interesting. This time <code>BinarySearch()<\/code> returns <code>-2<\/code>. Because the value is negative, we know the item was not found in the list. Taking the complement yields an index of <code>1<\/code>, and so we insert the item at this location. After inserting, our final list looks like this: <code>{1, 3, 5, 5}<\/code><\/p>\n<h3>Adding a Range of Elements<\/h3>\n<p>When it comes to adding a range of elements, we have two options. One option is to loop over the elements, calling our <code>Add()<\/code> method to insert each one in the proper location. The other option is to add them all to the end of the list and then sort it. We have chosen to implement the latter option due to the overall performance improvement. For completeness, let&#8217;s take a look at the method:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">public void AddRange(IEnumerable&lt;T&gt; items)\r\n{\r\n    _list.AddRange(items);\r\n    _list.Sort(_comparer);\r\n}<\/pre>\n<p>If the collection being added is small, there is not much difference in performance between the two options. As <code>items<\/code> length increases, we will begin to see a difference in performance (to not stray too far from the topic of the article, we are leaving measuring the performance as an exercise to the reader). The main reason is that <code>Add()<\/code>, on average, inserts elements into the middle of the list. Each time this occurs, the element at the chosen index and all following elements must be shifted down by one. As the number of elements being inserted grows, the cost involved in moving the elements becomes larger. By contrast, adding all the elements at once reduces the number of large copies being done.<\/p>\n<h2>Conclusion<\/h2>\n<p>In this article, we have explored several different techniques for sorting a list in place. We have looked at <code>List.Sort()<\/code> and its associated overloads, and we have implemented our own always-sorted collection. One thing we have not mentioned is using LINQ to enumerate our collection in an ordered fashion. Never fear, we have an <a href=\"https:\/\/code-maze.com\/linq-sorting-and-filtering\/\" target=\"_blank\" rel=\"noopener\">article<\/a> covering exactly that topic, so be sure to check it out!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this article, we will explore different techniques for sorting a list. A common task we face as developers is the need to sort a collection of data. The C# language provides us with a variety of ways in which we can accomplish this task. To help us have a better understanding of the available [&hellip;]<\/p>\n","protected":false},"author":6,"featured_media":62189,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_et_pb_use_builder":"","_et_pb_old_content":"","_et_gb_content_width":"","footnotes":""},"categories":[12],"tags":[1811,1468,1469,376,1195,592],"class_list":["post-94710","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-csharp","tag-c","tag-icomparable","tag-icomparer","tag-list","tag-list-sorting","tag-sorting","et-has-post-format-content","et_post_format-et-post-format-standard"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v24.7 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Techniques for Sorting a List in C# - Code Maze<\/title>\n<meta name=\"description\" content=\"In this article, we will explore different techniques for sorting a List. We will examine List.Sort and the LINQ ordering extensions.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/code-maze.com\/csharp-techniques-for-sorting-list\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Techniques for Sorting a List in C# - Code Maze\" \/>\n<meta property=\"og:description\" content=\"In this article, we will explore different techniques for sorting a List. We will examine List.Sort and the LINQ ordering extensions.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/code-maze.com\/csharp-techniques-for-sorting-list\/\" \/>\n<meta property=\"og:site_name\" content=\"Code Maze\" \/>\n<meta property=\"article:published_time\" content=\"2023-08-07T03:44:44+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-csharp.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1100\" \/>\n\t<meta property=\"og:image:height\" content=\"620\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Code Maze\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@https:\/\/twitter.com\/CodeMazeBlog\" \/>\n<meta name=\"twitter:site\" content=\"@CodeMazeBlog\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Code Maze\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"17 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":[\"Article\",\"BlogPosting\"],\"@id\":\"https:\/\/code-maze.com\/csharp-techniques-for-sorting-list\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/code-maze.com\/csharp-techniques-for-sorting-list\/\"},\"author\":{\"name\":\"Code Maze\",\"@id\":\"https:\/\/code-maze.com\/#\/schema\/person\/09d29b223012c8e94a68ba62861d0b04\"},\"headline\":\"Techniques for Sorting a List in C#\",\"datePublished\":\"2023-08-07T03:44:44+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/code-maze.com\/csharp-techniques-for-sorting-list\/\"},\"wordCount\":2954,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/code-maze.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/code-maze.com\/csharp-techniques-for-sorting-list\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-csharp.png\",\"keywords\":[\"C#\",\"IComparable\",\"IComparer\",\"list\",\"list sorting\",\"sorting\"],\"articleSection\":[\"C#\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/code-maze.com\/csharp-techniques-for-sorting-list\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/code-maze.com\/csharp-techniques-for-sorting-list\/\",\"url\":\"https:\/\/code-maze.com\/csharp-techniques-for-sorting-list\/\",\"name\":\"Techniques for Sorting a List in C# - Code Maze\",\"isPartOf\":{\"@id\":\"https:\/\/code-maze.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/code-maze.com\/csharp-techniques-for-sorting-list\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/code-maze.com\/csharp-techniques-for-sorting-list\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-csharp.png\",\"datePublished\":\"2023-08-07T03:44:44+00:00\",\"description\":\"In this article, we will explore different techniques for sorting a List. We will examine List.Sort and the LINQ ordering extensions.\",\"breadcrumb\":{\"@id\":\"https:\/\/code-maze.com\/csharp-techniques-for-sorting-list\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/code-maze.com\/csharp-techniques-for-sorting-list\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/code-maze.com\/csharp-techniques-for-sorting-list\/#primaryimage\",\"url\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-csharp.png\",\"contentUrl\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-csharp.png\",\"width\":1100,\"height\":620,\"caption\":\"C# Development\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/code-maze.com\/csharp-techniques-for-sorting-list\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/code-maze.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Techniques for Sorting a List in C#\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/code-maze.com\/#website\",\"url\":\"https:\/\/code-maze.com\/\",\"name\":\"Code Maze\",\"description\":\"Learn. Code. Succeed.\",\"publisher\":{\"@id\":\"https:\/\/code-maze.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/code-maze.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/code-maze.com\/#organization\",\"name\":\"Code Maze\",\"url\":\"https:\/\/code-maze.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/code-maze.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez.png\",\"contentUrl\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez.png\",\"width\":3511,\"height\":3510,\"caption\":\"Code Maze\"},\"image\":{\"@id\":\"https:\/\/code-maze.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/x.com\/CodeMazeBlog\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/code-maze.com\/#\/schema\/person\/09d29b223012c8e94a68ba62861d0b04\",\"name\":\"Code Maze\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/code-maze.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez-150x150.png\",\"contentUrl\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez-150x150.png\",\"caption\":\"Code Maze\"},\"description\":\"This is the standard author on the site. Most articles are published by individual authors, with their profiles, but when several authors have contributed, we publish collectively as a part of this profile.\",\"sameAs\":[\"https:\/\/www.linkedin.com\/company\/codemaze\/\",\"https:\/\/x.com\/https:\/\/twitter.com\/CodeMazeBlog\"],\"url\":\"https:\/\/code-maze.com\/author\/codemazecontributor\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Techniques for Sorting a List in C# - Code Maze","description":"In this article, we will explore different techniques for sorting a List. We will examine List.Sort and the LINQ ordering extensions.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/code-maze.com\/csharp-techniques-for-sorting-list\/","og_locale":"en_US","og_type":"article","og_title":"Techniques for Sorting a List in C# - Code Maze","og_description":"In this article, we will explore different techniques for sorting a List. We will examine List.Sort and the LINQ ordering extensions.","og_url":"https:\/\/code-maze.com\/csharp-techniques-for-sorting-list\/","og_site_name":"Code Maze","article_published_time":"2023-08-07T03:44:44+00:00","og_image":[{"width":1100,"height":620,"url":"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-csharp.png","type":"image\/png"}],"author":"Code Maze","twitter_card":"summary_large_image","twitter_creator":"@https:\/\/twitter.com\/CodeMazeBlog","twitter_site":"@CodeMazeBlog","twitter_misc":{"Written by":"Code Maze","Est. reading time":"17 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":["Article","BlogPosting"],"@id":"https:\/\/code-maze.com\/csharp-techniques-for-sorting-list\/#article","isPartOf":{"@id":"https:\/\/code-maze.com\/csharp-techniques-for-sorting-list\/"},"author":{"name":"Code Maze","@id":"https:\/\/code-maze.com\/#\/schema\/person\/09d29b223012c8e94a68ba62861d0b04"},"headline":"Techniques for Sorting a List in C#","datePublished":"2023-08-07T03:44:44+00:00","mainEntityOfPage":{"@id":"https:\/\/code-maze.com\/csharp-techniques-for-sorting-list\/"},"wordCount":2954,"commentCount":0,"publisher":{"@id":"https:\/\/code-maze.com\/#organization"},"image":{"@id":"https:\/\/code-maze.com\/csharp-techniques-for-sorting-list\/#primaryimage"},"thumbnailUrl":"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-csharp.png","keywords":["C#","IComparable","IComparer","list","list sorting","sorting"],"articleSection":["C#"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/code-maze.com\/csharp-techniques-for-sorting-list\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/code-maze.com\/csharp-techniques-for-sorting-list\/","url":"https:\/\/code-maze.com\/csharp-techniques-for-sorting-list\/","name":"Techniques for Sorting a List in C# - Code Maze","isPartOf":{"@id":"https:\/\/code-maze.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/code-maze.com\/csharp-techniques-for-sorting-list\/#primaryimage"},"image":{"@id":"https:\/\/code-maze.com\/csharp-techniques-for-sorting-list\/#primaryimage"},"thumbnailUrl":"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-csharp.png","datePublished":"2023-08-07T03:44:44+00:00","description":"In this article, we will explore different techniques for sorting a List. We will examine List.Sort and the LINQ ordering extensions.","breadcrumb":{"@id":"https:\/\/code-maze.com\/csharp-techniques-for-sorting-list\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/code-maze.com\/csharp-techniques-for-sorting-list\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/code-maze.com\/csharp-techniques-for-sorting-list\/#primaryimage","url":"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-csharp.png","contentUrl":"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-csharp.png","width":1100,"height":620,"caption":"C# Development"},{"@type":"BreadcrumbList","@id":"https:\/\/code-maze.com\/csharp-techniques-for-sorting-list\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/code-maze.com\/"},{"@type":"ListItem","position":2,"name":"Techniques for Sorting a List in C#"}]},{"@type":"WebSite","@id":"https:\/\/code-maze.com\/#website","url":"https:\/\/code-maze.com\/","name":"Code Maze","description":"Learn. Code. Succeed.","publisher":{"@id":"https:\/\/code-maze.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/code-maze.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/code-maze.com\/#organization","name":"Code Maze","url":"https:\/\/code-maze.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/code-maze.com\/#\/schema\/logo\/image\/","url":"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez.png","contentUrl":"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez.png","width":3511,"height":3510,"caption":"Code Maze"},"image":{"@id":"https:\/\/code-maze.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/x.com\/CodeMazeBlog"]},{"@type":"Person","@id":"https:\/\/code-maze.com\/#\/schema\/person\/09d29b223012c8e94a68ba62861d0b04","name":"Code Maze","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/code-maze.com\/#\/schema\/person\/image\/","url":"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez-150x150.png","contentUrl":"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez-150x150.png","caption":"Code Maze"},"description":"This is the standard author on the site. Most articles are published by individual authors, with their profiles, but when several authors have contributed, we publish collectively as a part of this profile.","sameAs":["https:\/\/www.linkedin.com\/company\/codemaze\/","https:\/\/x.com\/https:\/\/twitter.com\/CodeMazeBlog"],"url":"https:\/\/code-maze.com\/author\/codemazecontributor\/"}]}},"_links":{"self":[{"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/posts\/94710","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/users\/6"}],"replies":[{"embeddable":true,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/comments?post=94710"}],"version-history":[{"count":5,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/posts\/94710\/revisions"}],"predecessor-version":[{"id":94739,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/posts\/94710\/revisions\/94739"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/media\/62189"}],"wp:attachment":[{"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/media?parent=94710"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/categories?post=94710"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/tags?post=94710"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}