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

Mat*_*vey 3 c# operator-overloading implicit-cast implicit-conversion

假设我有一个简单的对象支持对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();
    }
}
Run Code Online (Sandbox Code Playgroud)

现在让我们说我的程序的另一部分我用字符串进行比较:

var companyCode = { some company code object }

if (companyCode == "MSFTUKCAMBS")
    // do something...
Run Code Online (Sandbox Code Playgroud)

编译器对==运算符做了什么?是否隐式将companyCode转换为字符串并运行System.String ==实现?它是否正在使用System.Object ==实施?或者编译器会抱怨我?(我现在没有编译器来检查这个).

据我所知,我还有其他几种选择.

  • ==(String x)在CompanyCode上实现运算符.
  • IEquatable<String>在CompanyCode上实现接口.

这些选项中的任何一个(或两个)是否更可取?

Jon*_*eet 5

假设我有一个简单的对象支持对System.String的隐式转换

我会质疑这个设计决定.事实上,它提出了运算符重载的问题,这表明你的同事会问同样的问题.我甚至不知道答案(就编译器将要做的事情而言).

我绝对不会建议实施IEquatable<string>,因为那时x.Equals(y)不会与之对称y.Equals(x).你可以==在你的类中实现两个重载,两种方式都是圆形的......但是那样就不一致了Equals.

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

if (companyCode.Value == "MSFTUKCAMBS")
Run Code Online (Sandbox Code Playgroud)

并且将立即清楚这意味着什么.

基本上,我认为隐式转换适当的情况非常少而且很远.

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

如果最终用户未明确预期此类转换,请勿提供转换运算符.

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

  • @JonSkeet 我担心的是人们将值与调用堆栈上方某处的行为(通过暴露的 _value 或 ToString)分离,然后将原始值向下传递 - 导致我现在所处的相同情况该行为是重复的。有什么方法可以确保行为遵循它所到之处的值,同时仍然允许字符串比较? (2认同)