Implicit Cast Operator and Equality Operator

Let's say I have a simple object that supports implicit casting to 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();
    }
}

      

Now, let's say in another part of my program, I'm doing a string comparison:

var companyCode = { some company code object }

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

      

What does the compiler do with the operator ==

? Is this implicitly casting companyCode into a string and doing the implementation System.String ==

? Is the implementation in use System.Object ==

? Or will the compiler just complain about me? (I don't have a compiler to test this right now).

As far as I can see, I have several other options.

  • Embed the operator ==(String x)

    in CompanyCode.
  • Implement the interface IEquatable<String>

    in CompanyCode.

Would be preferred (or both) of these options?

+3


source to share


3 answers


I personally suggest not using operator overloading

, in these cases. It's a little confusing looking at the code to figure out what's going on.

It's much better imo, having some function that explicitely exposes the comparison operation, or as John says it uses a property.



Briefly make it clear to the reader of your code what you are going to compare.

+2


source


Let's say I have a simple object that supports implicit casting to System.String

I would question this design decision. The fact that he raised this issue of operator overloading suggests that your colleagues will be asking the same questions. I don't even know the answer (in terms of what the compiler will do) off the top of my head.

I would definitely not suggest implementing IEquatable<string>

, since then x.Equals(y)

it would not be symmetrical with y.Equals(x)

. You could implement two overloads ==

in your class, both paths are round ... but then this is not consistent with Equals

.

I would suggest just having a property named Value

or a Code

string of type, then you can use:

if (companyCode.Value == "MSFTUKCAMBS")

      



and it will be immediately clear what this means.

Basically, I think that situations where implicit conversions are appropriate are very few and far between.

From Design Guidelines for Class Library Developers

Do not provide a conversion operator unless the end users explicitly expected the conversion.

Is there such a clear expectation here?

+5


source


It will implicitly cast the string and check for equality using the string == operator. For the case that you are showing, each method you suggested is appropriate, but each path has a different purpose and meaning.

Implicit conversion should generally be avoided. The == implementation is to allow string comparisons, and IEquatable simply allows the class to be used as an IEquatable type for external code references. IEquatable can return a == result very simply.

In this case, I would choose to overload the == operator unless you have any other purpose for using implicit conversion.

Also, if you are using implicit conversions, it will be a little uglier but smarter but smarter to overload the EXPLICIT conversion rather than the implicit one, so when you want to convert your class to a string, it will have to use it (string) obj, which is also a good reminder of what's really going on in the code.

+2


source







All Articles