是C#a = b = c;等于b = c;一个= C;而C ++是b = c; A = B;?

时间:2011-04-08 04:22:04

标签: c#

换句话说,C#operator =会返回正确的值,不是吗?但是C ++通常会返回左边的值,对吗?

3 个答案:

答案 0 :(得分:10)

不,赋值表达式的结果是赋值,右边的表达式。所以考虑一下:

    byte a;
    int b;
    byte c = 10;

    a = b = c; // Fails to compile

这无法编译,因为尽管b = c有效,但它是int类型的表达式,然后无法将其分配给类型为a的{​​{1}}

从C#4语言规范,第7.17.1节:

  

简单赋值表达式的结果是赋给左操作数的值。结果与左操作数的类型相同,并且始终归类为值。

编辑:以下证明它是分配给byte使用的值, b的值:

c

using System; class ACType { public int Value { get; set; } public static implicit operator BType(ACType ac) { return new BType { Value = ac.Value / 2 }; } } class BType { public int Value { get; set; } public static implicit operator ACType(BType b) { return new ACType { Value = b.Value / 2 }; } } class Test { static void Main() { ACType a, c; BType b; c = new ACType { Value = 100 }; a = b = c; Console.WriteLine(a.Value); // Prints 25 } } 语句相当于:

a = b = c;

之后BType tmp = c; b = tmp; a = tmp; 的值不是(它不等同于b) - 所以如果b = c; a = b;实际上是属性,那么行为除了副作用之外,财产是无关紧要的。它是 b 分配中使用的任何值,它也用于b的分配。

在这种情况下,对a的分配需要从b转换为ACType,这会创建值为{50的BType。然后,对BType的分配需要从a转换为BType,从而创建值为{25的ACType

答案 1 :(得分:9)

不,它在两个语言中都是一样的:a = b = c;的工作方式如下:a = (b = c);。赋值运算符从右向左工作,返回的值是赋值的结果,即左侧。因此,从概念上讲,a = b = c;与:b = c; a = b;相同。

对于C#,赋值运算符和条件运算符(?:)是右关联的,这意味着操作是从右到左执行的。例如,x = y = z被评估为x =(y = z)。 (Source

C ++(Source

相同

答案 2 :(得分:2)

关于a = b = c语义的有用信息是a确实会收到分配的相同值(通常 c *) bb当前值不是一个因素。

是的,这可能会让人感到意外。考虑一下这个例子:

class Foo
{
    private int _bar;
    public int Bar
    {
        get { return _bar; }
        set { _bar = value + 1; }
    }
}

...

Foo foo = new Foo();
int a, c;
c = 4;

a = foo.Bar = c; // is 'a' 4 or 5? 

如果值通过foo.Bar并且变异进入a,则a将为5.但是,这不是发生的事情。 afoo.Bar获得相同的值,a未收到foo.Bar的变异。这不是你直接提出的问题,但考虑到一些意见后,发表这篇文章很有意思。


* Jon Skeet对于可隐式转换为彼此但在转换中有数据丢失/修改的类型有一个有趣的观察。在这种情况下,该值可能c的原始值,但转换后的值可能不同。