是C#a=b=C;等于b=c;a=c;鉴于C++;是b=c;a=b;?

是C#a=b=C;等于b=c;a=c;鉴于C++;是b=c;a=b;?,c#,C#,换句话说,C#operator=将返回正确的值,不是吗?但是C++通常返回左值,对?< P>不,在两种语言中都是相同的: A= B= C;的工作原理如下:a=(b=c)。赋值运算符从右向左工作,返回的值是赋值的结果,即左侧。所以在概念上,a=b=c与:b=c;a=b 对于C#,赋值运算符和条件运算符(?:)是右关联的,这意味着操作是从右向左执行的。例如,x=y=z的计算结果为x=(y=z)。() (C++)< p>不,赋值表达式的结果是赋值,而不是右边的表达式。所以考虑一下: byte

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

< P>不,在两种语言中都是相同的:<代码> A= B= C;<代码>的工作原理如下:
a=(b=c)。赋值运算符从右向左工作,返回的值是赋值的结果,即左侧。所以在概念上,
a=b=c
与:
b=c;a=b

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


(C++)

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

    byte a;
    int b;
    byte c = 10;

    a = b = c; // Fails to compile
这无法编译,因为尽管
b=c
是有效的,但它是
int
类型的表达式,因此无法将其分配给
a
,后者的类型为
byte

根据C#4语言规范第7.17.1节:

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

编辑:这里有证据证明是分配给所使用的
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
转换为
BType
,从而创建一个
BType
,其值为50。然后,对
a
的赋值需要从
b类型
转换为
ACType
,这将创建一个
ACType
,其值为25。

关于
a=b=c
语义的一个有用的小贴士是
a
确实会收到分配给
b
的相同值(通常
c
*),
b
的现值不是一个因素

是的,这可能被认为是令人惊讶的。考虑这个例子:

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。然而,事实并非如此
a
foo.Bar
接收相同的值,
a
不接收来自
foo.Bar
的突变。这不是直接问你的问题,但考虑到一些评论,这很有趣



*Jon Skeet对类型进行了有趣的观察,这些类型可以隐式地相互转换,但在转换过程中会丢失/修改数据。在这种情况下,值很可能不是
c
的原始值,而是转换后的值,这可能会有所不同。

正是出于这个原因,我避免使用这种语法-代码的作用应该是显而易见的。@Kragen:1)事情不是这样发生的。2) 即便如此,可能会产生什么不同的行为?@kirkdunno,但是
a=c;b=c(写在两行上时)甚至不必考虑任何可能的歧义,并使其明显有两个赋值。@Kragen,大概两个
=
建议两个赋值?(值得一提的是,应该与
b=c;a=b
@Kirk进行比较,如果a、b和c都是property,如果它们也是不同类型的隐式overided强制类型呢?调用了什么getter/setter,调用了什么强制类型?我不是说你不能解决它(或者说这很困难),只是两个简单的作业不应该涉及这种精神负担。这个问题已经有4个不同的答案(其中一个是错误的!)…虽然
a=b
是有效的…你的意思是
b=a
?@Hemant:抱歉,它被破坏了。修复了-并将其反转,使其更像原始的。有趣的是表达式
a=b=c
的总体值可能与此处任何变量的值完全不同,这可能根本不等于我知道,这是你帮助我学习的一部分,我希望在我的编码活动中从来没有真正考虑过。“安东尼:这是多么有趣的今天,昨天又有一个复杂的指派问题,听起来不像听起来那么简单:谢谢。现在我要做噩梦了。是的,我遇到了类似的事情。这是我的例子,虽然我使用了索引器。程序的结果让我怀疑,所以我发布了这个问题。我仍然在学习C,现在我相信C的属性和索引器是返回操作符=规则的左值的例外…@鲍伯,考虑乔恩Switt的答案中的文本。“简单赋值表达式的结果是分配给左操作数的值。”它不是左操作数的值,因为可能已经发生了变化(如上所示)并产生意外的结果。它的值并不总是与
c
相同。想象两种类型彼此进行隐式转换,但会丢失数据,其中
a
c
是一种类型,而
b
是另一种类型。从
c
类型到
b
类型的转换将被执行ormed,然后将执行转换回
a
类型。@Jon,有趣的一点。我确实会测试在分配之前发生数据丢失的场景。@Jon…哇,是的,刚刚测试过。可能会有一个噩梦。我知道正确的运算符=将在fir进行计算