You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于《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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 00:09:24