繁体   English   中英

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

[英]Implicit cast operator and the equality operator

假设我有一个支持隐式转换为 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)对称。 可以在你的类中实现两个==重载,两种方式都可以......但是它与Equals不一致。

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

if (companyCode.Value == "MSFTUKCAMBS")

这意味着什么将立即清晰。

基本上,我认为适合隐式转换的情况非常少见。

来自类库开发人员设计指南

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

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

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

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

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

此外,如果您使用隐式转换,那么重载 EXPLICIT 转换而不是隐式转换在代码方面会更难看,但在健壮方面更聪明,因此每当有人想将您的类转换为字符串时,他都必须使用 (string)obj 投射它,这也是代码中真正发生的事情的一个很好的提醒。

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

这是一个更好的,imo,具有一些明确表现比较操作的功能,或者像 Jon 建议的那样,使用属性。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM