假设我有一个支持隐式转换为System.String
的简单对象public sealed class CompanyCode
{
public CompanyCode(String value)
{
// Regex validation on value format
_value = value;
}
private readonly String _value;
public override String ToString()
{
return _value;
}
static public implicit operator String(CompanyCode code)
{
if(code == null)
return null;
return code.ToString();
}
}
现在让我们说我的程序的另一部分我用字符串进行比较:
var companyCode = { some company code object }
if (companyCode == "MSFTUKCAMBS")
// do something...
编译器使用==
运算符做了什么?它是否隐式地将companyCode转换为字符串并运行System.String ==
实现?它是否使用System.Object ==
实现?或者编译器会抱怨我? (我现在没有编译器来检查这个。)
据我所知,我还有其他两种选择。
==(String x)
运算符。IEquatable<String>
界面。这些选项中的任何一个(或两个)是否更可取?
答案 0 :(得分:5)
假设我有一个支持隐式转换为System.String
的简单对象
我会质疑这个设计决定。事实上,它提出了运算符重载的问题,这表明你的同事会问同样的问题。我甚至不知道答案(就编译器将要做的事情而言)。
我绝对不会建议实施IEquatable<string>
,因为x.Equals(y)
不会与y.Equals(x)
对称。你可能在你的班级中实现==
的两个重载,两种方式都是圆的...但是它与Equals
不一致。
我建议只有一个名为Value
或Code
类型字符串的属性,然后你可以使用:
if (companyCode.Value == "MSFTUKCAMBS")
将立即明确这意味着什么。
基本上,我认为隐含转换适当的情况非常少而且很远。
来自Design Guidelines for Class Library Developers
如果最终用户没有明确期望这种转换,请不要提供转化运营商。
这里有这么明确的期望吗?
答案 1 :(得分:2)
我个人建议不要在这些情况中使用operator overloading
。查看代码,了解发生了什么,这有点令人困惑。
这是一个更好的,imo,有一些明确显示比较操作的功能,或者像Jon建议的那样,使用一个属性。
简而言之,为您的代码读者清楚地了解您要比较的内容。
答案 2 :(得分:2)
它将隐式转换为字符串并使用字符串的==运算符检查相等性。 对于你展示的情况 - 你提供的每种方式都是合适的,但每种方式都有不同的目的和意义。
通常应避免隐式转换。 实现==是为了与字符串进行比较, IEquatable只是允许使用类作为IEquatable类型,用于外部代码引用。 IEquatable可能只返回==结果。
对于这种情况,我会选择==运算符重载,除非你有任何其他目的使用隐式转换。
另外,如果你使用隐式转换,它会在代码方面更加丑陋但是更加健壮,可以重载EXPLICIT转换,而不是隐式转换,所以每当想要将类转换为字符串时,他将不得不使用(字符串)obj来强制转换它,这也是对代码中真正发生的事情的一个很好的提醒。