隐式强制转换运算符和相等运算符

本文关键字:运算符 转换 | 更新日期: 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不一致。

我建议只拥有一个名为ValueCode的字符串类型的属性,然后可以使用:

if (companyCode.Value == "MSFTUKCAMBS")

这意味着什么,我们马上就能明白。

基本上,我认为隐式转换是合适的情况很少。

从类库开发人员的设计指南

如果最终用户没有明确预期转换,则不要提供转换运算符。

这里有这样明确的期望吗?

它将隐式转换为字符串,并使用字符串的==运算符检查相等性。对于你展示的案例,你提供的每一种方式都是合适的,但每一种方法都有不同的目的和意义。

通常应避免间接转换。实现==是为了允许与字符串进行比较,而IEquatable只是允许将类作为类型IEquatable用于外部代码引用。IEquatable很可能只返回==结果。

对于这种情况,我会选择==运算符重载,除非您有任何其他使用隐式转换的目的。

此外,如果您使用隐式转换,那么重载EXPLICIT转换(而不是隐式转换)在代码方面会有点难看,但在健壮方面会更聪明。因此,无论何时,只要想将类转换为字符串,都必须使用(string)obj进行强制转换,这也是一个很好的提醒,提醒您代码中实际发生了什么。

我个人建议不要使用operator overloading,在这些情况下。查看代码,了解发生了什么,这有点令人困惑。

imo,这是一个更好的方法,它有一些函数,明确地表示比较操作,或者像Jon建议的那样,使用一个属性。

简而言之,让代码的读者清楚地知道你要比较什么。