How does ThenBy work with Comparer? #71343
-
Good afternoon, colleagues. I have a question. Program class: var list = new List<SiteMapModel>()
{
new() { Level = 0, Name = "A0", Publish = DateTime.UtcNow },
new() { Level = 1, Name = "A1", Publish = DateTime.UtcNow.AddDays(5) },
new() { Level = 1, Name = "A11", Publish = DateTime.UtcNow.AddDays(4) },
new() { Level = 1, Name = "B1", Publish = DateTime.UtcNow.AddDays(6) },
new() { Level = 1, Name = "C1", Publish = DateTime.UtcNow.AddDays(4) },
new() { Level = 0, Name = "B0", Publish = DateTime.UtcNow.AddDays(1) },
new() { Level = 0, Name = "C0", Publish = DateTime.Now },
new() { Level = 2, Name = "A2", Publish = DateTime.UtcNow.AddDays(5) }
};
var comparerList = list.OrderBy(x => x.Name).ToList().OrderBy(x => x, new SiteMapComparer());
foreach (var model in comparerList)
{
Console.WriteLine($"{new string(' ', 2 * model.Level)}{model.Name}(level:{model.Level})");
} Model: public sealed class SiteMapModel
{
public string Name { get; set; }
public int Level { get; set; }
public DateTime Publish { get; set; }
} IComparer object: public sealed class SiteMapComparer : IComparer<SiteMapModel>
{
public int Compare(SiteMapModel? x, SiteMapModel? y)
{
if (ReferenceEquals(x, y))
return 0;
if (ReferenceEquals(null, y))
return 1;
if (ReferenceEquals(null, x))
return -1;
var nameComparison = string.Compare(x.Name, y.Name, StringComparison.Ordinal);
var dateCompare = DateTime.Compare(x.Publish, y.Publish);
if (x.Level != y.Level)
{
return nameComparison;
}
if (x.Level == y.Level)
{
return dateCompare;
}
return default;
}
} If writing is not beautiful: var comparerList = list.OrderBy(x => x.Name).ToList().OrderBy(x => x, new SiteMapComparer()); Sorting works as I want! var comparerList = list.OrderBy(x => x.Name).ThenBy(x => x, new SiteMapComparer()); I don't get into Comparer and sorting doesn't work as it should! Why is this happening? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
First, in your initial chained
To answer the Essentially, |
Beta Was this translation helpful? Give feedback.
First, in your initial chained
OrderBy
, you can drop theToList()
.var comparerList = list.OrderBy(x => x.Name).ToList().OrderBy(x => x, new SiteMapComparer());
to
var comparerList = list.OrderBy(x => x.Name).OrderBy(x => x, new SiteMapComparer());
To answer the
ThenBy
question:Essentially,
ThenBy
does not perform a completeOrderBy
again, otherwise, it would just duplicateOrderBy()
.OrderBy
will order the list by a key (x.Name
in this case).ThenBy
allows you to apply subsequent ordering on the items belonging to the same key.Since your provided list has no duplicate
Name
keys, theSiteMapComparer
will never be called as there is only 1 item to sort, so it is skipped.