ToString and string concatenation - unexpected behavior

拥有回忆 提交于 2019-12-07 14:16:27

问题


According to the internet when you do

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

ToString() is called on 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);

Prints:

a
b("key":"foo")

How is it possible?

I made Resharper full cleanup on whole project and it broke code in some place because it removed ToString() in such string concat!! Lost many hours..

Edit: This problem happened in one of small libraries I was using. I cannot provide very short one-file code that will reproduce this but I have created small project with this library and uploaded to github:

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

The library is 1178 lines long.


回答1:


This can happen if you have provided an implicit operator converting your class to a string, for instance:

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 that 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 could also get this effect if you have overloaded the + 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, user-defined implementations can be introduced by including operator declarations in classes and structs (Section 10.9). User-defined operator implementations always take precedence over predefined operator implementations: Only when no applicable user-defined operator implementations exist will the predefined operator implementations be considered.

That's why the custom logic gets invoked in preference to the standard logic.




回答2:


I just did this and it is working perfectly

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";
    }
}

Prints

ffThis is string

Which tells me that you do something wrong. I mean, not as much that you do wrong as much as you expect something different than your objects produce in ToString



来源:https://stackoverflow.com/questions/27770138/tostring-and-string-concatenation-unexpected-behavior

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!