换句话说,C# operator=将返回正确的值,不是吗?但是C++通常会返回左边的值,对吧?
发布于 2011-04-08 12:30:13
不,赋值表达式的结果是赋值的值,而不是右侧的表达式。因此请考虑以下内容:
byte a;
int b;
byte c = 10;
a = b = c; // Fails to compile这无法编译,因为虽然b = c是有效的,但它是int类型的表达式,因此不能将其赋给byte类型的a。
来自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,这将创建一个带有Value=50的BType。然后,对a的赋值需要从BType转换为ACType,这将创建一个带有Value=25的ACType。
发布于 2011-04-08 12:28:10
不,它在两种语言中都是一样的:a = b = c;的工作方式是这样的:a = (b = c);。赋值运算符从右到左工作,返回的值是赋值的结果,即左侧。所以从概念上讲,a = b = c;和b = c; a = b;是一样的。
对于C#,赋值运算符和条件运算符(?:)是右关联的,这意味着操作从右到左执行。例如,x=y=z的计算结果为x= (y = z)。(Source)
C++ (Source)也是如此
发布于 2011-04-08 12:38:38
关于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的原始值,而是转换后的值,这可能是不同的。
https://stackoverflow.com/questions/5590392
复制相似问题