C# ToString和字符串串联-意外行为
你什么时候上网C# ToString和字符串串联-意外行为,c#,resharper,C#,Resharper,你什么时候上网 String someString = "" + object1 + object2 + object3; 对每个对象调用ToString() 但这并没有发生! 此代码: String a = "a" + foo; String b = "b" + foo.ToString(); Console.WriteLine(a); Console.WriteLine(b); 印刷品: a b("key":"foo") 怎么可能呢 我对整个项目进行了Resharper完全清理,它在
String someString = "" + object1 + object2 + object3;
对每个对象调用ToString()
但这并没有发生!
此代码:
String a = "a" + foo;
String b = "b" + foo.ToString();
Console.WriteLine(a);
Console.WriteLine(b);
印刷品:
a
b("key":"foo")
怎么可能呢
我对整个项目进行了Resharper完全清理,它在某些地方破坏了代码,因为它删除了此类字符串concat中的ToString()
!!损失了很多小时
编辑:
这个问题发生在我正在使用的一个小型库中。我不能提供很短的一个文件代码来重现这一点,但我已经用这个库创建了一个小项目,并上传到github:
这个库有1178行长。我刚刚做了这个,它工作得非常好
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";
}
}
印刷品
这是字符串
这告诉我你做错了什么。我的意思是,如果您提供了将类转换为字符串的方法,则可能会发生这种情况,例如:
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;
}
}
在这种情况下:
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
如果使用forstring
和Foo
,也可以获得这种效果
更新
根据C语言规范:
所有一元运算符和二元运算符都有预定义的实现,可在任何表达式中自动使用。除了预定义的实现之外,还可以通过在类和结构中包含运算符声明来引入用户定义的实现。用户定义的运算符实现始终优先于预定义的运算符实现:只有当不存在适用的用户定义运算符实现时,才会考虑预定义的运算符实现
这就是为什么会优先调用自定义逻辑而不是标准逻辑。因此,该站点不适合解决编码难题(问题看起来像是当前状态下的问题)。如果需要帮助,请显示完整(最好是可编译的)小样本。
a
如果对象返回String.Empty,则可能是正确的b
看起来像是创建了一个匿名类型。@AlexeiLevenkov我已经创建了一个尽可能短的项目,在那里我可以复制它并上传到github。你说“根据互联网”调用了ToString
,但你自己的例子似乎证明了这一点。也许是互联网错了,或者更可能的是,在这个场景中有更多的规则,而不是总是调用ToString
,我自己也创建了自定义的简单案例,并且成功了。但它在某些情况下不起作用,就像我上传的那个一样。@vistrium,它还是按设计工作的。无论你上传什么,它都会起作用。例如,如果我重写ToString
并在其中抛出异常,我将在concatenation.Nice上得到异常。我不知道C#支持Scala之类的隐式转换。结果表明,Resharper清理会破坏您的代码,这是Resharper的错。小心!第一种情况(当存在到字符串的隐式转换时,首选“字符串+字符串”而不是“字符串+对象”)在“如果存在从T1到T2的隐式转换,并且不存在从T2到T1的隐式转换,则C1是更好的转换”一节中介绍“如果存在从字符串
到对象`的隐式转换,并且不存在从对象
到字符串
的隐式转换,则将自定义时间隐式转换为字符串
是更好的转换。”