是C#a=b=C;等于b=c;a=c;鉴于C++;是b=c;a=b;?
换句话说,C#operator=将返回正确的值,不是吗?但是C++通常返回左值,对?< P>不,在两种语言中都是相同的:<代码> A= B= C;<代码>的工作原理如下:是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
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进行计算