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
如果使用for
string
Foo
,也可以获得这种效果

更新

根据C语言规范:

所有一元运算符和二元运算符都有预定义的实现,可在任何表达式中自动使用。除了预定义的实现之外,还可以通过在类和结构中包含运算符声明来引入用户定义的实现。用户定义的运算符实现始终优先于预定义的运算符实现:只有当不存在适用的用户定义运算符实现时,才会考虑预定义的运算符实现


这就是为什么会优先调用自定义逻辑而不是标准逻辑。

因此,该站点不适合解决编码难题(问题看起来像是当前状态下的问题)。如果需要帮助,请显示完整(最好是可编译的)小样本。
a
如果对象返回String.Empty,则可能是正确的
b
看起来像是创建了一个匿名类型。@AlexeiLevenkov我已经创建了一个尽可能短的项目,在那里我可以复制它并上传到github。你说“根据互联网”调用了
ToString
,但你自己的例子似乎证明了这一点。也许是互联网错了,或者更可能的是,在这个场景中有更多的规则,而不是总是调用
ToString
,我自己也创建了自定义的简单案例,并且成功了。但它在某些情况下不起作用,就像我上传的那个一样。@vistrium,它还是按设计工作的。无论你上传什么,它都会起作用。例如,如果我重写
ToString
并在其中抛出异常,我将在concatenation.Nice上得到异常。我不知道C#支持Scala之类的隐式转换。结果表明,Resharper清理会破坏您的代码,这是Resharper的错。小心!第一种情况(当存在到字符串的隐式转换时,首选“字符串+字符串”而不是“字符串+对象”)在“如果存在从T1到T2的隐式转换,并且不存在从T2到T1的隐式转换,则C1是更好的转换”一节中介绍“如果存在从
字符串
到对象`的隐式转换,并且不存在从
对象
字符串
的隐式转换,则将自定义时间隐式转换为
字符串
是更好的转换。”