隐式强制转换运算符和相等运算符
本文关键字:运算符 转换 | 更新日期: 2023-09-27 18:28:42
假设我有一个简单的对象,它支持隐式转换为System.String
public sealed class CompanyCode
{
public CompanyCode(String value)
{
{ Regex validation on value format }
_value = value;
}
readonly String _value;
public override String ToString() => _value;
static public implicit operator String(CompanyCode code) =>
code?.ToString();
}
现在让我们假设在我的程序的另一部分中,我用字符串进行比较:
var companyCode = { some company code object }
if (companyCode == "MSFTUKCAMBS")
// do something...
编译器对==
运算符做了什么?它是否隐式地将companyCode转换为字符串并运行System.String ==
实现?它是否使用System.Object ==
实现?还是编译器会对我抱怨?(我现在没有编译器来检查这个)。
据我所知,我还有其他几个选择。
- 在CompanyCode上实现
==(String x)
运算符 - 在CompanyCode上实现
IEquatable<String>
接口
这些选项中的任何一个(或两个)会更可取吗?
假设我有一个简单的对象,它支持隐式转换为System.String
首先,我会对这个设计决定提出质疑。事实上,它提出了操作员过载的问题,这表明你的同事也会问同样的问题。我甚至不知道答案(就编译器将做什么而言)。
我肯定不会建议实现IEquatable<string>
,因为那样x.Equals(y)
就不会与y.Equals(x)
对称。您可以在类中实现==
的两个重载,双向。。。但与CCD_ 10不一致。
我建议只拥有一个名为Value
或Code
的字符串类型的属性,然后可以使用:
if (companyCode.Value == "MSFTUKCAMBS")
这意味着什么,我们马上就能明白。
基本上,我认为隐式转换是合适的情况很少。
从类库开发人员的设计指南
如果最终用户没有明确预期转换,则不要提供转换运算符。
这里有这样明确的期望吗?
它将隐式转换为字符串,并使用字符串的==运算符检查相等性。对于你展示的案例,你提供的每一种方式都是合适的,但每一种方法都有不同的目的和意义。
通常应避免间接转换。实现==是为了允许与字符串进行比较,而IEquatable只是允许将类作为类型IEquatable用于外部代码引用。IEquatable很可能只返回==结果。
对于这种情况,我会选择==运算符重载,除非您有任何其他使用隐式转换的目的。
此外,如果您使用隐式转换,那么重载EXPLICIT转换(而不是隐式转换)在代码方面会有点难看,但在健壮方面会更聪明。因此,无论何时,只要想将类转换为字符串,都必须使用(string)obj进行强制转换,这也是一个很好的提醒,提醒您代码中实际发生了什么。
我个人建议不要使用operator overloading
,在这些情况下。查看代码,了解发生了什么,这有点令人困惑。
imo,这是一个更好的方法,它有一些函数,明确地表示比较操作,或者像Jon建议的那样,使用一个属性。
简而言之,让代码的读者清楚地知道你要比较什么。