Microsoft User Group Винница feedback Интересно о C#: простые присвоения не всегда простые - Alex Krakovetskiy blog - Microsoft User Group Винница

 

Интересно о 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.

Таким образом, получаем финальную версию выражения: результатом простого присвоения является значение, которое было присвоено левому элементу.

Источник


Поділитись


Related Posts with Thumbnails Posted фев 28 2010, 08:16 by Краковецкий А. View 1 377 6

Comments

progg.ru on 02-28-2010 12:15

Thank you for submitting this cool story - Trackback from progg.ru

may be on 02-28-2010 13:20

может быть вы не понимаете разницы между ссылочными и размерными типамиЮ и что произходит при призмоении между разными типами?

noname on 02-28-2010 13:49

детский сад какойто

AvP on 02-28-2010 15:55

Автор не вводи в заблуждение неокрепшие умы(Свой ты уже завел).

1 присвоение является правосторонним

2 z = y

3 short y

* Почему это по вашему у 'z' должен быть тип Int32

вы же сами приводили пример со скобками, ну дык посмотрите на него еще н-раз, покуда не поймете.

Краковецкий А. on 03-01-2010 3:39

Мне кажется, что не совсем понятен смысл рубрики "Интересно о C#". Это переводы из блога Eric Lippert (Microsoft C# Compiler Team, stackoverflow.com/.../eric-lippert), поэтому детского сада, поверьте, тут точно нет.

Во вторых, я не говорю, что я что-то понимаю либо не понимаю - эти статьи предназначены для более точного понимания отдельных вещей языка C#.

Я никогда не использовал ситуации, когда присвоение идет для переменных разных типов, соответственно понимание такого рода мелочей поможет "неокрепшим умам" (да и мне тоже) тщательней относиться к мелочам.

А вот если вы заметили огрехи перевода - тогда, согласен, нужно на это указать и исправить.

AvP on 03-01-2010 7:43

Aric(а) поправили в коментариях.

Писать/Переводить статьи "для более точного понимания отдельных вещей языка C#" с ошибками/неточностями/заблуждениями не то что-бы не коректно а вредно и для самого автора и его последователей.

x = y - "The value resulting from the evaluation and conversion of y is stored into the location given by the evaluation of x." т.е. "В переменную х присваевается значение полученое из переменной y и сконверитрованое до типа х". Это же значение будет результатом присвоения, т.е. в выражении z = x = y в переменную z присваевается значение полученое из переменной y и сконверитрованое до типа х и в свою очередь сконверитрованое до типа z.

Для примера:

1

const int x = 10;

short y;

object z;

для: z = y = x;

имеем: y = (short)x & z = (object)((short)x);

для: y = x; z = y;

имеем: y = (short)x & z = (object)y;

2

class C

{

 private string x;

 public string X {

   get { return x ?? ""; }

   set { x = value; } }

}

   C c = new C();

   object z;

для: z = c.X = null;

имеем: c.X = null & z = (object)null;

для: z = c.X;c.X = null;

имеем: c.X = null & z = (object)c.X;

Вот на эту разницу и надо обращать внимание когда пишеш такое выражение!

Add a Comment

(required)  
(optional)
(required)  
Remember Me?
Please add 6 and 5 and type the answer here:

Enter captcha:

Информация

О нас
Timeline
Спонсоры
Поддержать

Разделы

Блоги
Медиа
Форумы
Вики
Презентации

Работа

Вакансии
Компании

Проекты

TechPosters
Data Mining SDK
Численные методы на C#
iPhoner
Data Extracting SDK

Контакты

msugvn@gmail.com
krakovetsky.alex
@msugvnua
ВКонтакте
LinkedIn
Facebook
INETA

Разработка логотипа: Helen

Статистика

Powered by Community Server (Non-Commercial Edition), by Telligent Systems