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

能否为非泛型BindingFilter与泛型BindingFilter<T>实现双向相等判断?

问题描述

我有两个类:非泛型的BindingFilter和泛型的BindingFilter<T>:

非泛型BindingFilter代码

public class BindingFilter 
{
    public object Value { get; set; }
    public string Member { get; set; }
  
    public BindingFilter(string member, object value)
    {
        Value = value ?? default!;
        Member = member;
    }

    public override bool Equals(object? obj)
    {
        if(obj == null)
        {
            return false;
        }

        if(obj is BindingFilter other)
        {
            return Member == other.Member && ( 
                (Value is null && other.Value is null) 
                || Equals(Value, other.Value) 
            );
        }

        return false;
    }
}

泛型BindingFilter<T>代码

public class BindingFilter<T>
{
    public T? Value { get; set; }
    public string Member { get; set; }

    public BindingFilter(string member, object? value)
    {
        Member = member;
        Value = (T?)value ?? default!;
    }

    public override bool Equals(object? obj)
    {
        if (obj is BindingFilter<T> other)
        {
            return Member == other.Member && Equals(Value, other.Value);
        }

        if (obj is BindingFilter untyped)
        {
          return Member == untyped.Member && Equals(Value, untyped.Value);
        }

        return false;
    }
}

需要实现BindingFilter与BindingFilter<T>的双向相等判断,对应以下两个测试:

测试代码

[Fact]
public void TypedBindingFilterEqualsUntypedBindingFilter() {
  var filter1 = new BindingFilter("ColumnName", string.Empty);
  var filter2 = new BindingFilter<string?>("ColumnName", string.Empty);
  Assert.True(filter2.Equals(filter1));
}

[Fact]
public void UntypedBindingFilterEqualsTypedBindingFilter() {
  var filter1 = new BindingFilter("ColumnName", string.Empty);
  var filter2 = new BindingFilter<string?>("ColumnName", string.Empty);
  Assert.True(filter1.Equals(filter2));
}

其中TypedBindingFilterEqualsUntypedBindingFilter测试通过,但UntypedBindingFilterEqualsTypedBindingFilter测试失败。请问是否可以实现该双向相等判断,使第二个测试通过?


解决方案

可以实现双向相等判断,问题根源是非泛型BindingFilter的Equals方法仅处理同类型实例,未识别泛型BindingFilter<T>对象。

修改非泛型BindingFilter的Equals方法,添加对泛型类型的处理逻辑:

public override bool Equals(object? obj)
{
    if (obj == null)
    {
        return false;
    }

    // 处理非泛型同类型实例
    if (obj is BindingFilter untypedOther)
    {
        return Member == untypedOther.Member && 
               (Value == null && untypedOther.Value == null || Equals(Value, untypedOther.Value));
    }

    // 识别并处理泛型BindingFilter<T>实例
    var objType = obj.GetType();
    if (objType.IsGenericType && objType.GetGenericTypeDefinition() == typeof(BindingFilter<>))
    {
        // 通过反射获取泛型实例的Member和Value属性值
        var memberProperty = objType.GetProperty(nameof(Member));
        var valueProperty = objType.GetProperty(nameof(Value));
        
        if (memberProperty == null || valueProperty == null)
        {
            return false;
        }

        var otherMember = (string)memberProperty.GetValue(obj)!;
        var otherValue = valueProperty.GetValue(obj);

        return Member == otherMember && Equals(Value, otherValue);
    }

    return false;
}

修改后,第二个测试即可通过。核心要点:

  • 泛型类已支持与非泛型类的相等判断,需让非泛型类反向支持泛型实例
  • 利用反射识别泛型类型并读取属性,保证相等性的对称性(a.Equals(b)与b.Equals(a)结果一致)

补充:重写GetHashCode

为保证相等对象的哈希码一致(避免哈希集合异常),建议同时重写两个类的GetHashCode方法:

非泛型BindingFilter的GetHashCode

public override int GetHashCode()
{
    return HashCode.Combine(Member, Value);
}

泛型BindingFilter<T>的GetHashCode

public override int GetHashCode()
{
    return HashCode.Combine(Member, Value);
}

内容的提问来源于stack exchange,提问作者dgo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 09:38:09