我正在寻找实现IEquatable<T>
的最佳方式,以便隐式进行类型检查。如果我在子课程中拨打Equals
,我想确保I&amp; m比较的类型是相同的。请参阅下面的精简示例。
如果两个Child1
对象的ID相同,则应视为相等。在此示例中,如果它们的ID相同,则调用child1.Equals(child2)
将返回true,这不是预期的行为。我基本上希望强制Child1
的实例使用需要Equals
参数的Child1
重载,而不仅仅是从与Child1
相同的基类派生的参数
我开始认为我以错误的方式接近这一点。也许我应该在基类中保留Equals
的实现,并确保this.GetType() == other.GetType()
?
public abstract class BaseClass : IEquatable<BaseClass>
{
public int ID { get; set; }
public bool Equals(BaseClass other)
{
return
other != null &&
other.ID == this.ID;
}
}
public sealed class Child1 : BaseClass
{
string Child1Prop { get; set; }
public bool Equals(Child1 other)
{
return base.Equals(other as BaseClass);
}
}
public sealed class Child2 : BaseClass
{
string Child2Prop { get; set; }
public bool Equals(Child2 other)
{
return base.Equals(other as BaseClass);
}
}
答案 0 :(得分:3)
如果您确实需要“强制Child1
的实例使用需要Equals
参数的Child1
重载”,则可以使用C# Generics:
public abstract class BaseClass<T> : IEquatable<T>
where T : BaseClass<T>
{
public int ID { get; set; }
public bool Equals(T other)
{
return
other != null &&
other.ID == this.ID;
}
}
public sealed class Child1 : BaseClass<Child1>
{
string Child1Prop { get; set; }
public bool Equals(Child1 other)
{
return base.Equals(other);
}
}
public sealed class Child2 : BaseClass<Child2>
{
string Child2Prop { get; set; }
public bool Equals(Child2 other)
{
return base.Equals(other);
}
}
这确保您的“Equals”方法只能使用其定义的类型调用。
答案 1 :(得分:0)
你能比较每种类型吗?
return base.Equals(other as BaseClass) && this.GetType() is other.GetType();
这将比较变量实例化的实际类型。我在这里创建了一个.net小提琴:https://dotnetfiddle.net/rOeuuo
这是代码(在vb中)
Imports System
Public Module Module1
Public Sub Main()
dim x as testparent = new testchild1
dim y as testparent = new testchild2
if x.GetType() is y.Gettype() then
console.writeline("they are the same type")
else
console.writeline("they are different types")
end if
End Sub
End Module
public class testparent
end class
public class testchild1: inherits testparent
end class
public class testchild2: inherits testchild1
end class
这是另一个小提琴,其中两个子类直接从基类继承,而不是彼此继承(我认为这是你原来的问题):https://dotnetfiddle.net/ViNqej
Imports System
Public Module Module1
Public Sub Main()
dim x as testparent = new testchild1
dim y as testparent = new testchild2
if x.GetType() is y.Gettype() then
console.writeline("they are the same type")
else
console.writeline("they are different types")
end if
End Sub
End Module
public class testparent
end class
public class testchild1: inherits testparent
end class
public class testchild2: inherits testparent
end class
答案 2 :(得分:0)
这里有几个选项:
您可以在此检查每个Equals
方法中的实际运行时类型,并验证它不是您自己建议的子类型。这实际上是一个合理的解决方案。
您可以将每个Equals
方法设为虚拟。让每个派生类型覆盖其父Equals
方法,并静态return false
或尝试强制转换为&#34;您的&#34;如果可以,请输入return false
使用==
运算符代替Equals
。它的定义可能会也可能不会检查操作数的运行时类型,并验证它们不是子类型。
此处的一个关键行为是,您不必尝试阻止您的类型的用户将您的对象与另一种类型的对象进行比较。除了崩溃之外,你实际上有一个明智的行为。你可以return false
。你可以比较老虎和大象。它们有所不同,但你可以比较它们。