Интересно о C#: простые присвоения не всегда простые
Пусть у нас есть следующий код:
a = b = c;
Данный код является корректным и, в основном, используется в конструкциях типа:
int i, j, k;
i = j = k = 123;
Говорят, что данный код работает, потому что присвоение является правосторонним, а результатом присвоения будет значение правого элемента, т.е. следующий код будет эквивалентным предыдущему:
i = (j = (k = 123)));
Это значит, что нет никакого смысла ставить скобки. Но, в данном конкретном примере это работает, но в целом нет - результатом присвоения не будет значение правого элемента.
В примере:
const int x = 10;
short y;
object z;
z = y = x;
System.Console.WriteLine(z.GetType().ToString());
на экран выведется "System.Int16", а не ожидаемое "System.Int32". Результатом присвоения "y = x" будет int, но когда мы присваиваем результат к short, то на выходе мы получим short!
Поэтому правильное утверждение звучит как "результатом присвоения будет значение левого элемента".
Пусть у нас есть класс:
class C
{
private string x;
public string X {
get { return x ?? ""; }
set { x = value; } }
static void Main()
{
C c = new C();
object z;
z = c.X = null;
System.Console.WriteLine(z == null);
System.Console.WriteLine(c.X == null);
}
}
Этот код напечатает "True / False" – результат присвоения не является значением левого элемента - значение левого оператора является пустая строка, в то время как значение оператора присвоения - null.
Таким образом, получаем финальную версию выражения: результатом простого присвоения является значение, которое было присвоено левому элементу.