C# 为什么是;someString+;=另一个字符串=某个字符串&引用;在C中有效#

C# 为什么是;someString+;=另一个字符串=某个字符串&引用;在C中有效#,c#,.net-3.5,C#,.net 3.5,今天我正在写一些代码,当我在另一台显示器上用alt键切换到屏幕上检查一些东西时,我正在写代码。当我回头看时,ReSharper将下面的第三行涂成了灰色,并注意到“分配的值不用于任何执行路径” 我很困惑;这段代码肯定无法编译。但它确实如此,而且它也在运行。行“name+=”对字符串没有影响(我可以看出)。这是怎么回事 (VisualStudio2008.NET3.5)请注意,换行符在C#中并不特殊。由于下一行的原因,编译器的完整语句是 name += ltlName.Text = name; 这

今天我正在写一些代码,当我在另一台显示器上用alt键切换到屏幕上检查一些东西时,我正在写代码。当我回头看时,ReSharper将下面的第三行涂成了灰色,并注意到“分配的值不用于任何执行路径”

我很困惑;这段代码肯定无法编译。但它确实如此,而且它也在运行。行“name+=”对字符串没有影响(我可以看出)。这是怎么回事


(VisualStudio2008.NET3.5)

请注意,换行符在C#中并不特殊。由于下一行的原因,编译器的完整语句是

name += ltlName.Text = name;
这是一个有效的语句(它将
名称
分配给
ltlName.Text
,然后将其附加到
名称

它正在执行以下操作:

name += ltlName.Text = name;
或者说得更清楚一点:

name += (ltlName.Text = name);
属性setter的结果是设置的值,因此它的工作方式有点像这样:

string tmp = name;
ltlName.Text = tmp;
name += tmp;
不过,当涉及到不同的变量时,更容易观察到这一点,最后一步是简单赋值,而不是复合赋值。下面是一个完整的示例:

using System;

class Test
{
    public string Text { get; set; }

    static void Main()
    {
        Test t = new Test();

        string x = t.Text = "Hello";
        Console.WriteLine(x); // Prints Hello
    }
}
简单赋值规则(第7.17.1节)用于确定表达式的结果:

简单赋值的结果 表达式是指定给的值 左操作数。结果是 与左操作数的类型相同,为 始终分类为一个值

因此,
ltlName.Text=name
的类型与
ltlName.Text
的类型相同,并且该值是已分配的值。事实上,它是一个属性而不是一个字段或局部变量不会改变这一点。

在C#中,换行符不会终止语句,只有分号会终止语句。因此,正在执行以下代码行:

name += ltlName.Text = name;

因为空格在C#中是不相关的,所以第3、4和5行形成一条语句:

name += ltlName.Text = name;

它会影响字符串,但直到字符串用于影响显示上的文字后才会发生。正如KennyTM指出的,这两行构成了一个单独的语句。与VB不同,回车符不以C#结束语句。分号不起作用。因此,这里发生的是字符串被设置为文本,并且该操作的结果(“可能是真的?或者只是字符串本身?我不记得了)被附加到字符串中。

正如预期的那样,结果是名称连接到其自身。所以你得到了“名字”

Text只是一个属性,因此该行最终转换为

//name += obj.Text = name;
obj.setText(name);
name += obj.Text;
完整来源如下

public class Program
{
    public static void Main(string[] args)
    {
        MyClass obj = new MyClass();
        string name = "name";
        name += obj.Text = name;
        Console.Write(name); //prints namename
    }
}

你有两个监视器,炫耀….+1,用于发布你问题的所有相关代码,不多或少一行。@Baddie,我也有。可能再加上第三个。只是“因为”而已。@Baddie抱歉,我不是故意幸灾乐祸的@任务好吧,如果我只是像我最初计划的那样发布“name+=”,这个问题就不那么清楚了。它(大致)扩展为:
ltlName.Text=name;name=name+ltlName.Text。这相当于
ltlName.Text=name;名称=名称+名称这是有道理的。。。我在别处用这段代码测试了它:stringx=
“这是一个字符串!”;MessageBox.Show(x);x+=MessageBox.Show(x)但这也“隐藏”了我丢失的作业。谢谢连接不会创造出更多的名称吗?或者操作顺序会抵消concat吗?@Joel:不,它仍然在执行串联-赋值版本只是为了让事情更简单。将进行编辑以澄清。@Jon Skeet-在您的澄清中,不应该是字符串x+=t.Text=“Hello”;(每一个操作)并且那行的结果不会打印“HelloHello”?@Joel:不会。重点是要显示一个更简单的版本,它只是对一个新变量赋值-保持三个方面分开。您不能执行“string x+=…”,因为没有现有值。可能值得注意的是,在一个表达式中执行多个赋值的代码很难阅读,通常应该避免。(事实上,这是令人困惑的足以有一个关于它的问题张贴是证据!)
public class Program
{
    public static void Main(string[] args)
    {
        MyClass obj = new MyClass();
        string name = "name";
        name += obj.Text = name;
        Console.Write(name); //prints namename
    }
}