ToString and string concatenation - unexpected behavior

According to the internet when you do

String someString = "" + object1 + object2 + object3;

      

ToString()

called for each of the objects.

But this is not happening! This code:

String a = "a" + foo;
String b = "b" + foo.ToString();

Console.WriteLine(a);
Console.WriteLine(b);

      

Printing

a
b("key":"foo")

      

How is this possible?

I did a full Resharper cleanup for the whole project and it broke the code in some place because it removed ToString()

concat in such a line !! Many hours were lost.

Edit: This issue happened in one of the small libraries I used. I cannot provide a very short single file code that will reproduce it, but I created a small project with this library and uploaded it to github:

https://github.com/Vistritium/ToStringCSObjectConcat https://github.com/Vistritium/ToStringCSObjectConcat/blob/master/TestString/Program.cs

The library is 1178 lines long.

+3


source to share


2 answers


This can happen if you provided an implicit operator that converts your class to a string, for example:

public class Foo
{
    public string Key { get; set; }

    public string Value { get; set; }

    public static implicit operator string(Foo foo)
    {
        return foo == null ? string.Empty : foo.Value;
    }

    public override string ToString()
    {
        var str = string.Empty;
        if (!string.IsNullOrEmpty(Key))
        {
            if (str.Length > 0)
                str += ";";
            str += ("Key=" + Key);
        }
        if (!string.IsNullOrEmpty(Value))
        {
            if (str.Length > 0)
                str += ";";
            str += ("Value=" + Value);
        }
        return str;
    }
}

      

In this case:

    string a = "a" + new Foo { Key = "foo", Value = "" };
    string b = "b" + new Foo { Key = "foo", Value = "" }.ToString();

    Debug.WriteLine(a); // Prints "a".
    Debug.WriteLine(b); // Prints "bKey=foo

      

You can also get this effect, if the overloaded operator+

for string

and Foo

.



Update

From the C # Language Specification, 7.2.2 Operator Overloading :

All unary and binary operators have predefined implementations that are automatically available in any expression. In addition to the predefined implementations, custom implementations can be introduced by including statement declarations in classes and structs (section 10.9) . Custom operator implementations always take precedence over predefined operator implementations: only when there are no applicable custom operator implementations will the predefined operator implementations be considered.

This is why custom logic is called in preference to standard logic.

+4


source


I just did this and it works great

private void button1_Click(object sender, EventArgs e)
{
    var o = new x ();
    string s = "ff" + o;

    Console.WriteLine(s);

}

public class x {

    public override string ToString()
    {
        return "This is string";
    }
}

      

Printing



ff This is a line

Which tells me that you are doing something wrong. I mean, there is not much that you do not do as you expect inToString

+1


source







All Articles