interface I //: IEquatable<I>
{ }
class A : I
{
static public bool operator !=(A a, I i)
{
return !(a == i);
}
static public bool operator ==(A a, I i)
{
return true;
}
public override bool Equals(object obj)
{
if (obj is I)
return this == (I)obj;
else
return base.Equals(obj);
}
public override int GetHashCode()
{
return base.GetHashCode();
}
}
class B : I
{
static public bool operator !=(B b, I i)
{
return !(b == i);
}
static public bool operator ==(B b, I i)
{
return false;
}
public override bool Equals(object obj)
{
if (obj is I)
return this == (I)obj;
else
return base.Equals(obj);
}
public override int GetHashCode()
{
return base.GetHashCode();
}
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
List<I> iss = new List<I>();
A a = new A();
B b = new B();
iss.Add(a);
iss.Add(b);
if (iss[0] == iss[1])
Console.WriteLine("a == b");
else
Console.WriteLine("a != b");
if (iss[1] == iss[0])
Console.WriteLine("b == a");
else
Console.WriteLine("b != a");
}
}
输出
a != b
b != a
我期待
a == b
b != a
有人可以解释一下吗?
答案 0 :(得分:1)
我在每个类的Equals()方法和==运算符中设置断点,并查看调用每个表达式的内容。它显然不是你所期望的。我的猜测是,因为I
不能并且不能要求实现者公开==
运算符,所以当您正在比较两个I
时,运行时不会打扰寻找重载的运算符,而是转向System.Object ==
,它执行参考检查。
答案 1 :(得分:0)
简单回答:
您有一个List<I>
并且您将两个I
相互比较。因为interface I
没有(并且不能)实现比较运算符,所以通过引用来比较对象。
相反,您可以使用抽象基类:
public interface I
{
}
public abstract class AbstractI : I
{
public static bool operator ==(AbstractI left, I right)
{
return left.equals(right); //TODO can be null
}
public static bool operator !=(AbstractI left, I right)
{
return !left.equals(right);
}
protected abstract bool equals(I other);
}
public class A : AbstractI
{
protected override bool equals(I other)
{
//TODO your compare code here
throw new NotImplementedException();
}
}
public class B : AbstractI
{
protected override bool equals(I other)
{
//TODO your compare code here
throw new NotImplementedException();
}
}
List<AbstractI> l = new List<AbstractI>(){
new A(),
new B()
};
var x = l[0] == l[1];