我有一个带有两个覆盖==运算符的类,将它与该类的其他实例进行比较,并与string的实例进行比较。
class SomeClass
{
string value;
public SomeClass (string _Value)
{
value = _Value;
}
static public bool operator == (SomeClass C1, SomeClass C2)
{
return C1.value == C2.value;
}
static public bool operator != (SomeClass C1, SomeClass C2)
{
return C1.value != C2.value;
}
static public bool operator == (SomeClass C1, string C2)
{
return C1.value == (string) C2;
}
static public bool operator != (SomeClass C1, string C2)
{
return C1.value != (string) C2;
}
}
但是,当我尝试将此类与null进行比较时:
Console.WriteLine(someObject == null);
我收到以下错误:
Error CS0121: The call is ambiguous between the following methods or properties: `SomeClass.operator ==(SomeClass, SomeClass)' and `SomeClass.operator ==(SomeClass, string)'
我应该如何定义我的==覆盖,以便我仍然可以对此类的实例进行空查?
答案 0 :(得分:7)
由于您使用的是null
文字,因此编译器不知道要调用哪个方法,因为string
和SomeClass
都可以为空。
强制编译器选择其中一种方法的一种技术是对null进行类型转换。
Console.WriteLine(someObject == ((SomeClass)null));
或者更好的是,不是显式使用null
,而是使用default
关键字来获取空值(因为当T是引用类型时,default(T)
为空)。
Console.WriteLine(someObject == default(SomeClass));
答案 1 :(得分:5)
您可以在string
和SomeClass
之间创建隐式转换,而不是定义两个相等运算符:
class SomeClass
{
string value;
public SomeClass(string _Value)
{
value = _Value;
}
static public bool operator ==(SomeClass C1, SomeClass C2)
{
return C1.value == C2.value;
}
static public bool operator !=(SomeClass C1, SomeClass C2)
{
return C1.value != C2.value;
}
public static implicit operator string(SomeClass instance)
{
return instance.value;
}
public static implicit operator SomeClass(string str)
{
return new SomeClass(str);
}
//TODO override Equals and GetHashCode to use `value`
}
现在,当您将该值与null进行比较时,没有歧义问题。
这也有副作用,使类在其他地方可以隐式地相互转换,但是基于看起来不是坏事的上下文。
答案 2 :(得分:1)
对于那些迟到的人,请参阅下面的@Jeppe Stig Nielsen的评论中隐藏的更可接受的答案。
op已经具体询问了覆盖operator ==,但是,我相信这是覆盖==运算符时的一个重要信息,并且相信未来引用的正确答案应该是: -
Console.WriteLine((object)someObject == null);
使用接受的答案并在对象中实现==和Equals,您将继续得到相同的错误。最好与最低级别对象的null进行比较,这样您就可以将'object'与null进行比较,并且从比较中删除所有歧义。
以下是MSDN中实施的原因和解决方案:Guidelines for Overriding Equals() and Operator ==
请考虑以下内容,请参阅Equals实施中的注释: -
class SomeClass
{
string value;
public SomeClass(string _Value)
{
value = _Value;
}
static public bool operator ==(SomeClass C1, SomeClass C2)
{
return C1.value == C2.value;
}
public override bool Equals(SomeClass C1)
{
// causes error due to unsure which operator == to use the SomeClass == or the object ==
// Actual error: Operator '==' is ambiguous on operands of type 'SomeClass' and '<null>'
if (C1 == null)
return false;
// Give same error as above
if (C1 == default(SomeClass))
return false;
// Removes ambiguity and compares using base objects == to null
if ((object)C1 == null)
return false;
return value == C1.value;
}
}
答案 3 :(得分:0)
您可以将第二个参数作为“对象”传递,并在确定要执行的相等操作之前检查其类型。
static public bool operator == (SomeClass C1, object C2)
{
if(C2 is SomeClass)
return C1.value == ((SomeClass)C2).value;
else if (C2 is string)
return C1.value == (string) C2;
}