根据基数的等于()等待派生类

时间:2012-07-13 23:26:07

标签: c# inheritance casting

我有两个类,它们都来自同一个父级:

public class People{
    public string BetterFoot;

    public override bool Equals(object obj){
        if (obj == null || this.GetType() != obj.GetType())
            return false;
        People o = (People)obj;
        return (this.BetterFoot == o.BetterFoot);
    }

public class LeftiesOrRighties: People{
    public string BetterHand;

    public override bool Equals(object obj){
        if (obj == null || this.GetType() != obj.GetType())
            return false;
        LeftiesOrRighties o = (LeftiesOrRighties)obj;
        return (this.BetterFoot == o.BetterFoot) &&
        (this.BetterHand == o.BetterHand)
    }
}

public class Ambidextrous: People{
    public string FavoriteHand;
}

(那里也有GetHashCodes,但我知道它们有效。) 我想基于它们的根Equals()来比较它们的集合:

ThoseOneHanded = new List<LeftiesOrRighties>(){new LeftiesOrRighties(){BetterFoot = "L"}};
ThoseTwoHanded = new List<Ambidextrous>(){new Ambidextrous(){BetterFoot = "L"}};
//using NUnit
Assert.That ((People)ThoseOneHanded[0], Is.EqualTo((People)ThoseTwoHanded[0])));

不幸的是,这会返回false

为什么呢?铸件不应该制造它们(所有意图和用途,如果不是完全相同),因此使用基本方法?如果没有,我如何真正将基础类型转换回People

2 个答案:

答案 0 :(得分:2)

Cast不会更改对象本身,因此GetType的结果将始终相同,因此您的this.GetType() != obj.GetType()将为true,因此该函数将返回false。

以下逻辑可能会获得您想要的行为(并且您不需要强制转换为人员)

public class People 
{ 
    public string BetterFoot; 

    public override bool Equals(object obj)
    { 
        var o = obj as People;
        if (o == null) return false;
        return (this.BetterFoot = o.BetterFoot); 
} 

public class LeftiesOrRighties: People 
{ 
    public string BetterHand; 

    public override bool Equals(object obj) 
    { 
        var o = obj as LeftiesOrRighties; 
        if ( o == null) return base.Equals(obj);
        return (this.BetterFoot = o.BetterFoot) && (this.BetterHand = o.BetterHand) 
    } 
} 

public class Ambidextrous: People
{ 
    public string FavoriteHand; 
} 

答案 1 :(得分:1)

正如鲍勃·韦尔指出演员不会改变类型。

.Net框架中使用的标准解决方案是使用实现IEqualityComparer或其通用变体的自定义对象。比你的compare / find方法需要2个对象/集合,并使用comparer来执行自定义比较。

即。许多LINK方法采用自定义比较来查找/过滤 Enumerable.Distinct

等对象
public static IEnumerable<TSource> Distinct<TSource>(
    this IEnumerable<TSource> source,
    IEqualityComparer<TSource> comparer
)

样本比较器:

class Last3BitsComparer : IEqualityComparer<int>
{

  public bool Equals(int b1, int b2)
  {
    return (b1 & 3) == (b2 & 3);
  }
  public int GetHashCode(int bx)
  {
    return bx & 3;
  }
}