7

C# allows implicit conversions of integers to strings when used in an expression. For example, this is completely valid:

int myInt = 10;
string concatenatedString = "myInt is " + myInt;
string interpolatedString = $"myInt is {myInt}";

However, when the int is not being concatenated or interpolated, C# requires an explicit conversion.

int myInt = 10;
string myString = myInt; 
// compiler error "Cannot implicitly convert type 'int' to 'string'"

Obviously this isn't a major pain: a simple .ToString() takes care of this just fine. But if .NET knows that every possible int is also a valid string, why does it still require an explicit conversion? I'd like to know what's going on in the "mind" of the compiler.

  • 3
    I'll post this as a comment because it is only a guess. Concatenating strings seems pretty clear that you want the output to be a string. It probably also leverages the fact that all objects have a ToString method and treats the int like an object. Just assigning an int (or any other object) to a string should be possible (by calling ToString), which seems like most of the time would be an error. If the compiler allowed any object to be assigned to a string, would you want a MyClass object to implicitly convert to a string without an error or warning? I wouldn't. – Becuzz Oct 12 '16 at 12:24
  • 1
    Your question is about int specifically; what is special to you about int? You can add any expression that has a type convertible to object to a string. So either your question really should be "why can't C# convert object to string?" or you should say why you think that int is more deserving of this conversion than, say, decimal or IComparable<BigInteger> or System.Delegate. – Eric Lippert Oct 14 '16 at 16:01
  • $"{myInt}" (I'm told to add way more than 15 chars) – rwong Oct 17 '16 at 8:10
  • 1
    Have you ever been surprised when php or js do something unexpected because of implicit type casting? I think your answer likely lies there. – RubberDuck Oct 17 '16 at 9:29
  • 1
    @RubberDuck Most of those unexpected cases are due to lossy conversions, which this one is not. (Not saying that I like this particular implicit conversion) – CodesInChaos Oct 17 '16 at 10:28
14

In both cases, the language is offering syntactic sugar features, rather than doing implicit casting:

var s = "1" + 1;

is converted to the string Concat(object, object) method during compilation:

var s = String.Concat("1", 1);

And in the second case,

var i = 1;
var s = $"1={i}";

is converted to string Format(string, object) (or equivalent) method during compilation:

var s = string.Format("1={0}", i);

So in both cases, the int is being boxed to an object and each method then calls .ToString() on that object. No implicit casting is required.

As for the question in your title: "Why can't C# implicitly convert int to string?", the answer to that, is that neither the String class, not the Int32 struct implement the implicit operator, so implicit conversions aren't possible between those types. You might be interested to know though that post C# 7, one feature being considered for the language is called "Extension everything". This would allow you to add implicit conversions between various types and strings to the language, such that you could do something like:

string s = 1;

if you really wanted to. Of course, that raises the question, would you want to?

  • 1
    I remember reading somewhere (before C# 6 was rolled out) that string interpolation would use a heuristic approach to choose between String.Format and String.Concat. Wasn't that implemented? – ach Oct 12 '16 at 12:39
  • 1
    @AndreyChernyakhovskiy, I believe that string interpolation does indeed choose between a number of different approaches to implementing string interpolation. I've somewhat simplified things here in my answer. I think there are some good resources on SO on this topic, which I'll dig out if you'd like. – David Arno Oct 12 '16 at 12:46
  • 1
    @AndreyChernyakhovskiy, found what I was thinking of. There was much debate around how to handle cultures. By default String.Format is used, but you can force the interpolation down the IFormattable route to allow control over the interpolation. For example, see this question and answer from (of course) Jon Skeet. – David Arno Oct 12 '16 at 13:17
  • The C# designers can add implicit conversions without the types overloading the implicit operator. I'm pretty sure the widening integer conversions were implemented that way. They could have easily chosen to add such a built-in implicit conversion from integers to strings. – CodesInChaos Oct 17 '16 at 10:38
0

There are two common use cases for the "out-of-context" conversion of an integer to a string:

int myInt = 10;
string myString = myInt;

The first scenario creates a one-character string containing just a line-feed:

  • Pretend the decimal number 10 is a character.
  • Create a string containing just that character.

The second scenario creates a two-character string containing the digit "1" and the digit "0":

  • Perform an integer-to-ascii conversion of the integer 10.
  • Put the result in the new string.

If C# had implemented either of these alternatives, it is likely that many programmers would have written subtle bugs because they (incorrectly) assumed that the other alternative would work.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.