Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.54/13: Рейтинг темы: голосов - 13, средняя оценка - 4.54
Alvin Seville
332 / 265 / 131
Регистрация: 25.07.2014
Сообщений: 4,537
Записей в блоге: 9
1

Инициализация полей структур

11.10.2018, 16:00. Просмотров 2469. Ответов 45
Метки нет (Все метки)

Насколько знаю, у экземпляров классов поля всегда инициализируются значениями по умолчанию перед тем как в дело вступает конструктор. Почему у структур для инициализации полей используется конструктор по умолчанию для этих целей?
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
11.10.2018, 16:00
Ответы с готовыми решениями:

Инициализация массива структур
суть в чем. есть структура SS полем которой является матрица S. есть массив x - содержащий 8...

Инициализация структуры содержащей массив структур
Всем привет. на с# только начал писать, и нужно перенести сишный код в котором было несколько...

Не происходит инициализация полей
есть класс public class DinnerParty { private const int costOfFoodPerPerson = 30; ...

Инициализация полей классов
Сколько раз здесь будет инициализирован x? class InitialierTestClass { public...

45
Alvin Seville
332 / 265 / 131
Регистрация: 25.07.2014
Сообщений: 4,537
Записей в блоге: 9
11.10.2018, 18:06  [ТС] 21
Элд Хасп, а в непользовательском?
0
Эксперт .NET
14697 / 11111 / 2919
Регистрация: 17.09.2011
Сообщений: 18,650
11.10.2018, 18:12 22
Цитата Сообщение от Соколиный глаз Посмотреть сообщение
А что располагается внутри этого конструктора, если поля инициализируются до его вызова?
Ничего, он пуст.
0
Alvin Seville
332 / 265 / 131
Регистрация: 25.07.2014
Сообщений: 4,537
Записей в блоге: 9
11.10.2018, 18:16  [ТС] 23
kolorotur, а зачем вообще дефолтный конструктор структуре, если она им не пользуется? Ну, какой смысл, разве что писать
Код
var x = new StructName();
? Я всё понять этого не могу.
0
Модератор
8666 / 5991 / 1699
Регистрация: 21.04.2018
Сообщений: 17,806
Записей в блоге: 2
11.10.2018, 18:32 24
Цитата Сообщение от Соколиный глаз Посмотреть сообщение
а в непользовательском?
При объявлении переменой значимого типа, в том числе структуры, под неё выделяется память. Конструктор тогда не вызывается. Если надо создать экземпляр без объявления переменной, то тогда вызывается конструктор и создаётся область памяти под эту структуру.
C#
1
2
3
4
MeStruct inst; // Выделена память и к ней можно обращаться по имени переменной.
inst = new MeStruct() {Field1="Value"} ; // Выделена память под новую структуру, 
// записано значение в одно из полей этой структуры, 
// участок памяти структуры скопирован на участок памяти переменной.
0
Эксперт .NET
14697 / 11111 / 2919
Регистрация: 17.09.2011
Сообщений: 18,650
11.10.2018, 18:36 25
Цитата Сообщение от Соколиный глаз Посмотреть сообщение
а зачем вообще дефолтный конструктор структуре, если она им не пользуется?
Чтобы всегда имелась возможность проинициализировать переменную, имеющую тип этой струтуры.
Структуры ведь значимые типы — экземпляр хранится в переменной.
Обязательное наличие дефолтного конструктора исключает нежданчики вроде создания массива этих структур: массив — это набор переменных, значит при его инициализации переменные должны иметь какое-то значение. А какое, если у данной структуры нет дефолтного конструктора? А вот это-то и невозможно!
0
Alvin Seville
332 / 265 / 131
Регистрация: 25.07.2014
Сообщений: 4,537
Записей в блоге: 9
11.10.2018, 18:41  [ТС] 26
Цитата Сообщение от kolorotur Посмотреть сообщение
А какое, если у данной структуры нет дефолтного конструктора?
Тогда, получается он вызывается при создании массива.
0
Модератор
8666 / 5991 / 1699
Регистрация: 21.04.2018
Сообщений: 17,806
Записей в блоге: 2
11.10.2018, 18:43 27
Цитата Сообщение от Соколиный глаз Посмотреть сообщение
Тогда, получается он вызывается при создании массива.
Не только. Когда надо создать неименованный экземпляр.
0
Alvin Seville
332 / 265 / 131
Регистрация: 25.07.2014
Сообщений: 4,537
Записей в блоге: 9
11.10.2018, 18:45  [ТС] 28
А почему у классов конструктор по умолчанию определяется лишь тогда когда нет другого конструктора явно определенного с параметрами? Разве не может потребоваться просто так создать объект класса через конструктор по умолчанию?
0
Эксперт .NET
14697 / 11111 / 2919
Регистрация: 17.09.2011
Сообщений: 18,650
11.10.2018, 18:46 29
Цитата Сообщение от Соколиный глаз Посмотреть сообщение
Тогда, получается он вызывается при создании массива.
Формально — да.
Но представьте, что у вас в конструкторе по умолчанию имеется какой-то код инициализации: тогда ведь при создании массива на 100500 элементов придется делать 100500 вызовов этих конструкторов!
А если конструктор по умолчанию переопределить нельзя, то создание массива становится очень простым: выделяем память и зануляем все значения — это и соответствует правилам выделения памяти (обнулять перед использованием), и правилам инициализации экземпляров.
С одной стороны формально конструктор вроде как вызвался 100500 раз — наблюдается тот же эффект, а с другой эти вызовы делать не пришлось, потому что он пустой и никто этого изменить не может.
0
604 / 558 / 164
Регистрация: 17.07.2012
Сообщений: 1,592
Записей в блоге: 1
11.10.2018, 18:46 30
В C# не существует возможности определить конструктор по умолчанию для Value Types.
Я хз, что там будет если внаглую из MSIL попробовать дернуть безпараметрический конструктор, но через c# точно не дернуть. Именно потому что его нельзя вызвать из C#, его и объявить в C# нельзя.
Цитата Сообщение от Соколиный глаз Посмотреть сообщение
Тогда, получается он вызывается при создании массива.
Нет, никакие конструкторы вызываться не должны, ибо объекты при выделении массива не порождаются.
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Когда надо создать неименованный экземпляр.
И тут тоже нет.
0
Эксперт .NET
14697 / 11111 / 2919
Регистрация: 17.09.2011
Сообщений: 18,650
11.10.2018, 18:47 31
Цитата Сообщение от Соколиный глаз Посмотреть сообщение
А почему у классов конструктор по умолчанию определяется лишь тогда когда нет другого конструктора явно определенного с параметрами?
Чтобы писанины меньше было.

Цитата Сообщение от Соколиный глаз Посмотреть сообщение
Разве не может потребоваться просто так создать объект класса?
Правила инициализации для переменных ссылочных типов другие, потому можно как запретить создание конструктора по умолчанию, так и переопределить его поведение.
0
Модератор
8666 / 5991 / 1699
Регистрация: 21.04.2018
Сообщений: 17,806
Записей в блоге: 2
11.10.2018, 18:48 32
Цитата Сообщение от Cupko Посмотреть сообщение
И тут тоже нет.
А это как тогда назвать?
C#
1
inst = new MeStruct() {Field1="Value"} ;
0
Эксперт .NET
14697 / 11111 / 2919
Регистрация: 17.09.2011
Сообщений: 18,650
11.10.2018, 18:48 33
Цитата Сообщение от Cupko Посмотреть сообщение
Именно потому что его нельзя вызвать из C#
Мм?
C#
1
2
3
4
5
6
struct Foo
{
   public Foo(int x);
}
 
var foo = new Foo(); // OK
1
1108 / 779 / 219
Регистрация: 15.08.2010
Сообщений: 2,159
11.10.2018, 18:50 34
Цитата Сообщение от Элд Хасп Посмотреть сообщение
// участок памяти структуры скопирован на участок памяти переменной.
у меня так только в дебаге, в релизе сразу в нужную пишет послее ее инициализации дефолтом
0
Модератор
8666 / 5991 / 1699
Регистрация: 21.04.2018
Сообщений: 17,806
Записей в блоге: 2
11.10.2018, 18:53 35
Из документации"При создании экземпляра объекта структуры с помощью используемого по умолчанию конструктора без параметров все члены назначаются согласно их значениям по умолчанию."
0
604 / 558 / 164
Регистрация: 17.07.2012
Сообщений: 1,592
Записей в блоге: 1
11.10.2018, 18:54 36
Цитата Сообщение от kolorotur Посмотреть сообщение
Мм?
Видимо и я присоединяюсь к вопросу. Пойду посмотрю что в MSIL творится.
0
Модератор
8666 / 5991 / 1699
Регистрация: 21.04.2018
Сообщений: 17,806
Записей в блоге: 2
11.10.2018, 18:58 37
Цитата Сообщение от КОП Посмотреть сообщение
у меня так только в дебаге, в релизе сразу в нужную пишет послее ее инициализации дефолтом
Это, если у Вас идёт прямая инициализация. А если вы создаёте структуру в методе и потом её возвращаете или она создаётся в LINQ! Да, мало ли ещё способов.... Суть не в этом. При присваивании значимых типов копируются участки памяти. Но переменная всегда ссылается на один и тот же участок памяти.
0
1108 / 779 / 219
Регистрация: 15.08.2010
Сообщений: 2,159
11.10.2018, 19:02 38
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Это, если у Вас идёт прямая инициализация. А если вы создаёте структуру в методе и потом её возвращаете или она создаётся в LINQ!
я конкретно про ваш код говорил, остальное то понятно. Просто я не ожидал что в дебаге будет лишняя временная переменная, а в релизе (ожидаемо) её уже нет
0
604 / 558 / 164
Регистрация: 17.07.2012
Сообщений: 1,592
Записей в блоге: 1
11.10.2018, 19:13 39
Цитата Сообщение от kolorotur Посмотреть сообщение
Мм?
Но как бэ все равно никакой дефолтный конструктор не вызывается.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
    struct MyStruct
    {
        int Field;
 
        internal MyStruct(int field)
        {
            Field = field;
        }
    }
 
    class Program
    {
        static void Main(string[] args)
        {
            var x1 = new MyStruct();
 
            var x2 = new MyStruct(2);
 
            Console.ReadKey();
        }
    }
Код
  IL_0000:  nop
  IL_0001:  ldloca.s   x1
  IL_0003:  initobj    TestConsoleApp1.MyStruct
  IL_0009:  ldloca.s   x2
  IL_000b:  ldc.i4.2
  IL_000c:  call       instance void TestConsoleApp1.MyStruct::.ctor(int32)
  IL_0011:  call       valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()
  IL_0016:  pop
  IL_0017:  ret
Абсолютный эквивалент default(T).
Странно это все.
0
1108 / 779 / 219
Регистрация: 15.08.2010
Сообщений: 2,159
11.10.2018, 19:18 40
Cupko, можете ещё через Activator.CreateInstance попробовать, я там не смог разобраться в коде доходит ли до конструктора
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
11.10.2018, 19:18

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

Инициализация статических полей
Ковыряю legacy код, возможно нубский вопрос:( Есть глобальный класс со статическими полями и...

Инициализация полей структуры
Всем, привет. Такой вопрос, при написании вот такого кода в c# struct a { } int main() { ...

Обращение и инициализация полей класса
привет! помогите пожалуйста разобраться, как это работает. нужно понять что просходит под...

Инициализация в классе полей типа Enum
Добрый день! Есть класс, в нем есть поле перечисления. class Worker { private string...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.