问题
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