请参阅以下代码:
public class ValueType<T> where T : class,new()
{
public virtual bool Equals(T other)
{
if (other == null)
return false;
Type t = GetType();
Type otherType = other.GetType();
if (t != otherType)
return false;
FieldInfo[] fields = t.GetFields(System.Reflection.BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
foreach (FieldInfo field in fields)
{
object value1 = field.GetValue(other);
object value2 = field.GetValue(this);
if (value1 == null)
{
if (value2 != null)
return false;
}
else if (!value1.Equals(value2))
return false;
}
return true;
}
}
class Tiger : ValueType<Tiger> { public string name; public Tiger mother; }
class Program
{
static void Main(string[] args)
{
Tiger t1 = new Tiger() { name = "Teri" };
Tiger t2 = new Tiger() { name = "Teri" };
Tiger t3 = new Tiger() { name = "Toni", mother=t1 };
Tiger t4 = new Tiger() { name = "Toni", mother = t2 };
bool Test1 = t4.mother.Equals(t3.mother); //Highlighed line
bool Test2 = t4.Equals(t3);
}
}
我不明白为什么突出显示的行返回false。我希望它能在无限循环中运行。
答案 0 :(得分:1)
为什么你期望无限循环?返回true
而不是false
:
bool Test1 = t4.mother.Equals(t3.mother); .
不是因为母亲是平等的吗?它们具有相同的name
,并且没有&#34; grandmom&#34;。他们的mother
字段返回null
,因为Tiger
是引用类型(类)。
为什么
t4.Equals(t3)
会返回false
?
因为您已将其声明为Object
,所以使用Object.Equals
来比较引用。如果您尝试将其投射到Tiger
,则会调用此Equals
。
这就是为什么这不会导致无限循环但只返回false
(不是相同的参考):
...else if (!value1.Equals(value2))
请注意,您尚未覆盖Equals
。如果您这样做,您将获得预期的行为:
class Tiger : ValueType<Tiger> {
public string name; public Tiger mother;
public override bool Equals(object obj)
{
return ((ValueType<Tiger>) obj).Equals(this);
}
}
现在这可以按预期工作了。它不会导致无限递归,因为在某个时候父mother
将是null
,但如果母亲也是平等的,它将递归检查。
另一种方法是更改Equals
中现有ValueType
的签名:
public override bool Equals(Object other)