Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,22 @@
PrintProducts(productList);
Console.WriteLine();

Console.WriteLine("----------List<Product> In Place Sort With Comparer<T>.Create (Order: Price - Descending)----------");
Console.WriteLine("Products:");
PrintProducts(unsortedProducts);
Console.WriteLine();

productList.Clear();
productList.AddRange(unsortedProducts);

var byPriceDescending = Comparer<Product?>.Create(
(a, b) => Nullable.Compare(b?.Price, a?.Price));

productList.Sort(byPriceDescending);
Console.WriteLine("**Sorted**");
PrintProducts(productList);
Console.WriteLine();

Console.WriteLine("----------List<Product> In Place Sort With Comparison<T> (Lambda: Order - Category)----------");
Console.WriteLine("Products:");
PrintProducts(unsortedProducts);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public sealed record Product(string ProductName, string Category, decimal Price)
public static bool operator >=(Product? left, Product? right) =>
Comparer<Product>.Default.Compare(left, right) >= 0;

public static int DescendingCompare(Product? a, Product? b) => b?.CompareTo(a) ?? -1;
public static int DescendingCompare(Product? a, Product? b) => Comparer<Product>.Default.Compare(b, a);

public int CompareTo(object? obj)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,12 @@ public void CopyTo(Span<T> dest)
public int IndexOf(T item)
{
var index = _list.BinarySearch(item, _comparer);
if (index < 0) return -1;

return index < 0 ? -1 : index;
var comparer = _comparer ?? Comparer<T>.Default;
while (index > 0 && comparer.Compare(_list[index - 1], item) == 0) index--;

return index;
}

public void Insert(int index, T item)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ public sealed class ProductTests
public void Product_Default_Id_Should_Not_Be_Empty()
{
var product = new Product("Product A", "Category1", 10.0m);
product.Id.Should().NotBeEmpty();
Assert.NotEqual(Guid.Empty, product.Id);
}

[Fact]
Expand All @@ -16,26 +16,26 @@ public void Product_Comparisons_Should_Be_Correct()
var product2 = new Product("Product B", "Category1", 10.0m);
var product3 = new Product("Product A", "Category1", 20.0m);

product1.Should().BeLessThan(product2);
product1.Should().BeLessOrEqualTo(product2);
product2.Should().BeGreaterThan(product1);
product2.Should().BeGreaterOrEqualTo(product1);
Assert.True(product1 < product2);
Assert.True(product1 <= product2);
Assert.True(product2 > product1);
Assert.True(product2 >= product1);

product1.Should().NotBe(product3);
product1.CompareTo(product3).Should().BeNegative();
Assert.NotEqual(product1, product3);
Assert.True(product1.CompareTo(product3) < 0);

product1.CompareTo(product1).Should().Be(0);
Assert.Equal(0, product1.CompareTo(product1));
}

[Fact]
public void Product_Comparison_With_Null_Should_Be_Correct()
{
var product = new Product("Product A", "Category1", 10.0m);

product.Invoking(p => p.CompareTo(new object()))
.Should().Throw<ArgumentException>().WithMessage($"Object must be of type {nameof(Product)}");
var exception = Assert.Throws<ArgumentException>(() => product.CompareTo(new object()));
Assert.Equal($"Object must be of type {nameof(Product)}", exception.Message);

product.CompareTo(null).Should().Be(1);
Assert.Equal(1, product.CompareTo(null));
}

[Fact]
Expand All @@ -46,7 +46,7 @@ public void ShouldCorrectlyPerformDescendComparison_ForSameProducts_Ascending()

var result = Product.DescendingCompare(product1, product2);

result.Should().BePositive();
Assert.True(result > 0);
}

[Fact]
Expand All @@ -57,7 +57,7 @@ public void ShouldCorrectlyPerformDescendComparison_ForSameProducts_Descending()

var result = Product.DescendingCompare(product1, product2);

result.Should().BeNegative();
Assert.True(result < 0);
}

[Fact]
Expand All @@ -68,6 +68,30 @@ public void ShouldCorrectlyPerformDescendComparison_ForEqualProducts()

var result = Product.DescendingCompare(product1, product2);

result.Should().Be(0);
Assert.Equal(0, result);
}
}

[Fact]
public void DescendingCompare_ForTwoNulls_ReturnsZero()
{
Assert.Equal(0, Product.DescendingCompare(null, null));
}

[Fact]
public void DescendingCompare_WhenListHasManyNulls_SortsWithNullsLast()
{
var random = new Random(1);
var products = Enumerable.Range(0, 200)
.Select(i => i % 5 == 0 ? null : new Product($"P{random.Next(1000):D3}", "Category", 1m))
.ToList();

products.Sort(Product.DescendingCompare);

Assert.All(products.Take(160), Assert.NotNull);
Assert.All(products.Skip(160), Assert.Null);
Assert.Equal(
products.Take(160).OrderByDescending(p => p!.ProductName, StringComparer.OrdinalIgnoreCase)
.Select(p => p!.ProductName),
products.Take(160).Select(p => p!.ProductName));
}
}
Loading
Loading