简体   繁体   English

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

[英]Implicit cast operator and the equality operator

Say I have a simple object which supports implicit casting to System.String假设我有一个支持隐式转换为 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();
}

Now lets say in another part of my program I perform a comparison with a string:现在让我们说在我程序的另一部分中,我与一个字符串进行了比较:

var companyCode = { some company code object }

if (companyCode == "MSFTUKCAMBS")
    // do something...

What is the compiler doing with the == operator?编译==运算符做什么? Is it implicitly casting companyCode to a string and running the System.String == implementation?它是否将 companyCode 隐式转换为字符串并运行System.String ==实现? Is it using the System.Object == implementation?它是否使用System.Object ==实现? Or will the compiler just complain at me?或者编译器会抱怨我吗? (I don't have a compiler to check this right now). (我现在没有编译器来检查这个)。

As far as I can see I have a couple of other options.据我所知,我还有其他几个选择。

  • Implement an ==(String x) operator on CompanyCode.在 CompanyCode 上实现==(String x)运算符。
  • Implement the IEquatable<String> interface on CompanyCode.在 CompanyCode 上实现IEquatable<String>接口。

Would any (or both) of these options be preferable?这些选项中的任何一个(或两个)是否更可取?

Say I have a simple object which supports implicit casting to System.String假设我有一个支持隐式转换为 System.String 的简单对象

I would question this design decision to start with.我会质疑这个设计决定。 The fact that it's brought up this question of operator overloading suggests that your colleagues will be asking the same sort of questions.它提出了运算符重载的问题,这一事实表明您的同事会问同样的问题。 I don't even know the answer (in terms of what the compiler will do) off the top of my head.我什至不知道答案(就编译器会做什么而言)。

I definitely wouldn't suggest implementing IEquatable<string> , as then x.Equals(y) won't be symmetric with y.Equals(x) .我绝对不会建议实施IEquatable<string> ,因为这样x.Equals(y)不会与y.Equals(x)对称。 You could implement two overloads of == in your class, both ways round... but then it wouldn't be consistent with Equals .可以在你的类中实现两个==重载,两种方式都可以......但是它与Equals不一致。

I would suggest just having a property called Value or Code of type string, then you can use:我建议只拥有一个名为ValueCode的字符串类型的属性,然后您可以使用:

if (companyCode.Value == "MSFTUKCAMBS")

and it will be immediately clear what that means.这意味着什么将立即清晰。

Basically, I think the situations where implicit conversions are appropriate are very few and far between.基本上,我认为适合隐式转换的情况非常少见。

From the Design Guidelines for Class Library Developers来自类库开发人员设计指南

Do not provide a conversion operator if such conversion is not clearly expected by the end users.如果最终用户没有明确预期此类转换,则不要提供转换运算符。

Is there such a clear expectation here?这里有这么明确的期望吗?

It will implicitly cast to a string and check equality using the string's == operator.它将隐式转换为字符串并使用字符串的 == 运算符检查相等性。 For the case you show - every way you offered is suitable, but every way has a different purpose and meaning.对于您展示的案例 - 您提供的每一种方式都是合适的,但每种方式都有不同的目的和意义。

Implicitly conversion should usually be avoided.通常应避免隐式转换。 Implementing the == is to allow comparing with a string, and IEquatable is simply to allow using the class as type IEquatable, for outside code references.实现 == 是为了允许与字符串进行比较,而 IEquatable 只是允许将类用作 IEquatable 类型,用于外部代码引用。 The IEquatable may very well just return the == result. IEquatable 很可能只返回 == 结果。

For this case, I would choose the == operator overloading, unless you have any other purpose for using implicit conversion.对于这种情况,我会选择 == 运算符重载,除非您有使用隐式转换的任何其他目的。

Also, if you use implicit conversions, it will be a bit uglier code-wise but smarter robust-wise to overload an EXPLICIT conversion, and not an implicit one, so whenever one wants to convert your class to a string, he will have to cast it using (string)obj, which is also a good reminder for whats really happening in the code.此外,如果您使用隐式转换,那么重载 EXPLICIT 转换而不是隐式转换在代码方面会更难看,但在健壮方面更聪明,因此每当有人想将您的类转换为字符串时,他都必须使用 (string)obj 投射它,这也是代码中真正发生的事情的一个很好的提醒。

I personally would suggest do not use operator overloading , in these cases .这些情况下,我个人建议不要使用operator overloading It's kind of confusing looking on the code, to understand what is going on.查看代码有点令人困惑,以了解发生了什么。

It's a much better, imo, having some function that esplicitly manifests comparison operation, or, like Jon suggests, use a property.这是一个更好的,imo,具有一些明确表现比较操作的功能,或者像 Jon 建议的那样,使用属性。

In short make it clear for the reader of your code what you're gonna to compare.简而言之,让你的代码的读者清楚你要比较什么。

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

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