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

 

Интересно о C#: странное поведение структур

Рассмотрим следующий код:

struct S
{
private string blah;
public S(string blah)
{
this.blah = blah;
}
public void Frob()
{ // whatever
}
}

Следующий код будет работать:

S s1 = new S();
s1.Frob();

Каждая струкура имеет конструктор по умолчанию, в котором все поля иницилизируются со значениями по умолчанию. А как насчет этого кода?

S s2;
s2.Frob();

Похоже, мы увидем ошибку "Use of unassigned local variable 's2'". Интересной особенностью C# компилятора является тот факт, что ошибка присвоения будет выдана лишь в том случае, если структура компилируется с исходного кода. В случае, если структура находится в подключенной библиотеке, ошибка не будет выдана! Рассмотрим другой пример:

struct SS
{
public int x;
public int y;
public void Bar() {…}
}

Рассмотрим код, который использует структуру:

SS ss;
ss.x = 123;
ss.y = 456;
ss.Bar();

Вы не поверите, но этот код посностью рабочий! Локальная переменная s имеет две переменных - x и у. Если обоим переменным x и y присвоены значения, то s считается проинициализированной. Если был вызван конструктор, то все переменные автоматически инициализируются, в противном случае компилятор проверяет, все ли переменные структуры проинициализированны и если это так - не выдает ошибку.

Аномалия происходит по той причине, что когда компилятор видит структуру в исходном коде, то он проверяет все переменные и находит, что s1.blah не проинициализирована и выдает ошибку, что s1 также не проинициализирована. Но в случае, когда структура находится в библиотеке, компилятор игнорирует недоступные поля ссылочного типа. Выходит, что ни одно из полей не было проинициализировано из нуля доступных полей, которые необходимо инициализировать, но s1 все равно должна быть проинициализирована!

Замечание. Компилятор игнорирует лишь недоступные поля ссылочного типа, в том время когда численные типы проверяются.

Это поведение, несомненно, является странным. Думаю, что мы должны быть последовательными и либо рассматривать постоянно все поля, либо рассматривать только доступные поля все время, а не бегать вперед-назад в зависимости деталей процесса компиляции. Мой выбор был бы первым - заставлять пользователя вызывать конструктор по умолчанию или конструктор default(T). Данное поведение не является критическим, но было бы неплохо иметь одинаковое поведение.

Источник

P.S. Если вы заметили какие-либо неточности при переводе, прошу сообщить.


Поділитись


Related Posts with Thumbnails Posted фев 22 2010, 11:07 by Краковецкий А. View 985 3

Comments

progg.ru on 02-23-2010 7:06

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

dzlk on 02-25-2010 23:11

Если не ошибаюсь, то у Рихтера было описание про использование полей в структурах и их инициализацию

Может быть on 02-28-2010 5:35

автор поста забыл/не знал, что типы struct являются не ссылочными типами, а типами значений которые инициализируются при объявлении.

Add a Comment

(required)  
(optional)
(required)  
Remember Me?
Please add 3 and 7 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