Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot implicitly convert type 'X' to 'string' - when and how it decides that it "cannot"?

Right now I'm having it with Guids.

I certainly remember that throughout the code in some places this implicit conversion works, in others it does not. Until now I fail to see the pattern.

How the compiler decides when it cannot? I mean, the type method Guid.ToString() is present, isn't it called whenever this transformation is needed?

Can someone please tell me under what circumstances this transformation is done automatically and when I have to call myInstance.ToString() explicitly?

like image 315
User Avatar asked Apr 15 '09 11:04

User


3 Answers

In short, when there is an implicit or explicit conversion operator defined:

class WithImplicit {
    public static implicit operator string(WithImplicit x) {
        return x.ToString();}
}
class WithExplicit {
    public static explicit operator string(WithExplicit x) {
        return x.ToString(); }
}
class WithNone { }

class Program {
    static void Main() {
        var imp = new WithImplicit();
        var exp = new WithExplicit();
        var none = new WithNone();
        string s1 = imp;
        string s2 = (string)exp;
        string s3 = none.ToString();
    } 
}
like image 172
Marc Gravell Avatar answered Oct 20 '22 16:10

Marc Gravell


No, there is no implicit conversion from GUID to String, so that doesn't work anywhere at all in the code.

It only works where there is an explicit conversion, but the conversion might not be very visible. For example when you concatenate strings:

string id = "--" + guidValue + " : " + num;

This may look like an implicit conversion from GUID to String, but it isn't. The code that is generated actually looks like this:

string id = String.Concat(new object[] { "--", guidValue, " : ", num });

All operands are cast to the type Object and placed in an array. The String.Concat method then calls the ToString method for each item in the array to get the string representation for them.

like image 36
Guffa Avatar answered Oct 20 '22 14:10

Guffa


The only place where you effectively don't need to call ToString() yourself is when concatenating strings.

Guid g;
int i;
string s = "Hello "+g+' '+i;

Then there are some situations where the call is made by the .NET Framework, such as in String.Format().

Other than that, the compiler will only convert a type if it is known to be compatible (e.g. base class or implementing an interface or via an explicitly coded conversion operator). When you use a cast and the compiler knows that the types cannot be compatible (e.g. not in the same inheritance line, and not interfaces), it will also say that it cannot convert it. The same goes for generic type parameters.

like image 4
Lucero Avatar answered Oct 20 '22 15:10

Lucero