关于《Pro ASP.NET Core 6》中Comparer示例的理解困惑
问题描述
我正在自学C#,阅读A.Freeman所著《Pro ASP.NET Core 6》一书,将书中133页的示例简化为控制台应用,代码如下:
public class Program { static void Main(string[] args) { Product[] products = new Product[] { new Product { Name = "Kayak", Price = 275M }, new Product { Name = "Kayak", Price = 48.95M} }; Comparer.Get<Product>((p1, p2) => p1?.Name == p2?.Name); Console.WriteLine(Comparer.Equals(products[0], products[1])); Console.ReadKey(); } } public class Comparer { public static Comparer<U?> Get<U>(Func<U?, U?, bool> func) { return new Comparer<U?>(func); } } public class Comparer<T> : Comparer, IEqualityComparer<T> { private Func<T?, T?, bool> comparisonFunction; public Comparer(Func<T?, T?, bool> func) { comparisonFunction = func; } public bool Equals(T? x, T? y) { return comparisonFunction(x, y); } public int GetHashCode(T obj) { return obj?.GetHashCode() ?? 0; } } public class Product { public string Name { get; set; } = string.Empty; public decimal? Price { get; set; } public static Product[] GetProducts() { Product kayak = new Product { Name = "Kayak", Price = 275M }; Product lifejacket = new Product { Name = "Lifejacket", Price = 48.95M }; return new Product[] { kayak, lifejacket }; } }
我原本认为,调用Comparer.Get<Product>时传入的Lambda表达式会在执行Comparer.Equals(products[0], products[1])时,通过Comparer类的Equals方法被调用,但实际情况并非如此,想请教我的理解哪里出现了错误?
问题分析与解决
- 未保存自定义比较器实例:你调用
Comparer.Get<Product>(...)后,直接丢弃了返回的Comparer<Product?>实例——这个实例才是持有你传入的Lambda表达式的对象,后续代码根本没用到它。 - 调用的不是自定义Equals方法:你写的
Comparer.Equals(products[0], products[1]),实际调用的是object类的静态Equals方法(因为你的Comparer基类没有定义静态Equals方法,编译器会向上查找至object),这个方法只会比较两个对象的引用是否相等,和你自定义的比较逻辑完全无关。 - 正确使用方式:需要保存
Get方法返回的比较器实例,然后调用该实例的Equals方法,修改后的Main方法代码如下:
static void Main(string[] args) { Product[] products = new Product[] { new Product { Name = "Kayak", Price = 275M }, new Product { Name = "Kayak", Price = 48.95M} }; // 保存自定义比较器实例 var productComparer = Comparer.Get<Product>((p1, p2) => p1?.Name == p2?.Name); // 调用实例的Equals方法 Console.WriteLine(productComparer.Equals(products[0], products[1])); Console.ReadKey(); }
补充:你的Comparer<T>继承自Comparer基类其实没有必要,因为Comparer基类除了静态Get方法外没有其他成员,但这不是导致当前问题的原因。
内容的提问来源于stack exchange,提问作者ntfs
相关产品推荐
相关产品推荐

