Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.95/21: Рейтинг темы: голосов - 21, средняя оценка - 4.95
Alvin Seville
 Аватар для Соколиный глаз
346 / 276 / 134
Регистрация: 25.07.2014
Сообщений: 4,537
Записей в блоге: 22

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

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

Студворк — интернет-сервис помощи студентам
Насколько знаю, у экземпляров классов поля всегда инициализируются значениями по умолчанию перед тем как в дело вступает конструктор. Почему у структур для инициализации полей используется конструктор по умолчанию для этих целей?
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
11.10.2018, 16:00
Ответы с готовыми решениями:

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

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

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

45
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
11.10.2018, 20:33
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Cupko Посмотреть сообщение
Но как бэ все равно никакой дефолтный конструктор не вызывается.
Так это же скомпилированный код.
Если разговор о C#, то конструктор-то есть. Как там его компилятор обработает в целях оптимизации — это его дело, в конце-концов все превратится в ассемблер, где вообще без конструкторов
1
 Аватар для Cupko
660 / 597 / 171
Регистрация: 17.07.2012
Сообщений: 1,686
Записей в блоге: 1
11.10.2018, 20:42
kolorotur,
Так у меня какой-то диссонанс от таких оптимизаций
Я реально полагал что из шарпа вызвать конструктор явно нельзя. По той простой причине, что ему нечего инициализировать.
Т.е. в языке есть явный запрет на создание таких конструкторов, но нет запрета на вызов. А если учесть то, что он нигде не нужен (да и по факту, в MSIL, нигде и не вызывается), то вопрос "Зачем?", заданный выше, у меня тоже возникает.
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
11.10.2018, 21:04
Цитата Сообщение от Cupko Посмотреть сообщение
Так у меня какой-то диссонанс от таких оптимизаций
Вам надо пару лет на плюсах поработать — прививка от диссонансов на всю жизнь, т.к. после оптимизаций плюсового компилятра уже ничего не удивит

Цитата Сообщение от Cupko Посмотреть сообщение
в языке есть явный запрет на создание таких конструкторов, но нет запрета на вызов.
Так явный запрет на изменение его реализации, а в наличии он всегда.
Именно для уменьшения сюрпризов: переменная проинициализирована без вызова конструктора с параметрами (правила это позволяют), хотя другого не определено. Как так?!

Цитата Сообщение от Cupko Посмотреть сообщение
А если учесть то, что он нигде не нужен (да и по факту, в MSIL, нигде и не вызывается), то вопрос "Зачем?"
В смысле "нигде"?
Вы не сможете использовать переменную значимого типа без явной инциализации всех членов или без вызова конструктора — вот тут и нужен.
C#
1
2
3
4
5
6
7
8
9
10
11
struct Foo
{
   public int x;
   public string y;
}
 
void Bar()
{
   Foo foo;
   Console.WriteLine(foo.x); // Ататат, переменная foo не проинициализирована!
}
В примере выше чтобы избежать ошибки компиляции у вас есть два варианта:
1. Явно проинициализировать все члены перед первым использованием:
C#
1
2
3
4
5
Foo foo;
foo.x = 42;
foo.y = "Hello world!";
 
Console.WriteLine(foo.x); // OK
2. Вызвать дефолтный конструкор:
C#
1
2
Foo foo = new Foo();
Console.WriteLine(foo.x); // ОК
Второй вариант зачастую намного проще.
2
 Аватар для Cupko
660 / 597 / 171
Регистрация: 17.07.2012
Сообщений: 1,686
Записей в блоге: 1
11.10.2018, 21:36
kolorotur, спасибо, конечно, за примеры, но пока ничего логичнее не стало. Надо на досуге почитать/поэкспериментировать.
Все равно смахивает на какой-то очередной костыль. "чтобы избежать ошибки компиляции", как вы говорите
0
1123 / 794 / 219
Регистрация: 15.08.2010
Сообщений: 2,185
11.10.2018, 22:15
Итак, провел небольшой тест с подменой понятий dll. Вот результат. Что с ним делать я понятия не имею

для начала если добавить в конструктор вывод в консоль и скомпилить с этой библиотекой. (тестовый код ниже приведен)
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
Declaring local variable
 
Boxing
 
Lib.Structure
 
new Structure() - set local variable
Oddity constructor called
 
Create instance of Test - contains instance variable
 
new Structure() - set instance field
Oddity constructor called
 
new Structure() - set static field
Oddity constructor called
 
new Structure[10]
 
Passing argument to method
 
default(T) in generic method with new() constraint
 
new T() in generic method with new() constraint
Oddity constructor called
 
default(T) in generic method with struct constraint
 
new T() in generic method with struct constraint
 
Activator.CreateInstance(typeof(Structure))
 
Activator.CreateInstance<Structure>()


Далее я решил просто выставить значение i на 987 в конструкторе без параметров и потом выводить именно это значение.

Тестовый код:
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
namespace Lib
{
    public struct Structure
    {
        public int i;
    }
}

Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
using System;
using System.Runtime.CompilerServices;
using Lib;
 
namespace Test
{
    internal class Test
    {
        private static Structure staticField;
        private Structure instanceField;
 
        private static void Main()
        {
            Structure localDeclarationOnly;
            localDeclarationOnly.i = 2;
            Report("Declaring local variable", localDeclarationOnly);
            
            // No variables within the value, so we can use it
            // without inializing anything
            
            object o = localDeclarationOnly;
            Report("Boxing", (Structure)o);
            
            // Just make sure it’s really done it
            Report(o.ToString());
 
            var local = new Structure();
            Report("new Structure() – set local variable", local);
            
            var t = new Test();
            Report("Create instance of Test – contains instance variable", t.instanceField);
            
            t.instanceField = new Structure();
            Report("new Structure() – set instance field", t.instanceField);
           
            staticField = new Structure();
            Report("new Structure() – set static field", staticField);
            
            var a = new Structure[10];
            Report("new Structure[10]", a[0]);
            
           
            MethodWithParameter(local);
 
            GenericMethod<Structure>();
            GenericMethod2<Structure>();
            Report("Activator.CreateInstance(typeof(Structure))", (Structure)Activator.CreateInstance(typeof(Structure)));
 
            Report("Activator.CreateInstance<Structure>()", Activator.CreateInstance<Structure>());
 
            Console.ReadKey();
        }
 
        [MethodImpl(MethodImplOptions.NoInlining)]
        private static void MethodWithParameter(Structure Structure)
        {
            Report("Passing argument to method", Structure);
        }
 
        private static void GenericMethod<T>() where T : new()
        {
            object t = default(T);
            Report("default(T) in generic method with new() constraint", (Structure)t);
            
            t = new T();
            Report("new T() in generic method with new() constraint", (Structure)t);
            
        }
 
        private static void GenericMethod2<T>() where T : struct
        {
            object t = default(T);
            Report("default(T) in generic method with struct constraint", (Structure)t);
           
            t = new T();
            Report("new T() in generic method with struct constraint", (Structure)t);
           
        }
        private static void Report(string text)
        {
            Console.WriteLine();
            Console.WriteLine(text);
        }
 
        private static void Report(string text, Structure s)
        {
            Console.WriteLine();
            Console.WriteLine(text);
            Console.WriteLine(s.i);
        }
    }
}


И вот какой результат вышел. Там где передача в метод, там конструктор и не вызывается, но значение 987 идет копией из локала, лень уже править

1. Честная либа без всяких переопределений (двойка в начале так и задумана)
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
Clean
 
Declaring local variable
2
 
Boxing
2
 
Lib.Structure
 
new Structure() - set local variable
0
 
Create instance of Test - contains instance variable
0
 
new Structure() - set instance field
0
 
new Structure() - set static field
0
 
new Structure[10]
0
 
Passing argument to method
0
 
default(T) in generic method with new() constraint
0
 
new T() in generic method with new() constraint
0
 
default(T) in generic method with struct constraint
0
 
new T() in generic method with struct constraint
0
 
Activator.CreateInstance(typeof(Structure))
0
 
Activator.CreateInstance<Structure>()
0

2. Компиляция с подмененной dll
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
Compiled with declared default
 
Declaring local variable
2
 
Boxing
2
 
Lib.Structure
 
new Structure() - set local variable
987
 
Create instance of Test - contains instance variable
0
 
new Structure() - set instance field
987
 
new Structure() - set static field
987
 
new Structure[10]
0
 
Passing argument to method
987
 
default(T) in generic method with new() constraint
0
 
new T() in generic method with new() constraint
987
 
default(T) in generic method with struct constraint
0
 
new T() in generic method with struct constraint
0
 
Activator.CreateInstance(typeof(Structure))
0
 
Activator.CreateInstance<Structure>()
0

3. Компилячия с честрой либой, потом подмена ее на фейковую
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
replaced
 
Declaring local variable
2
 
Boxing
2
 
Lib.Structure
 
new Structure() - set local variable
0
 
Create instance of Test - contains instance variable
0
 
new Structure() - set instance field
0
 
new Structure() - set static field
0
 
new Structure[10]
0
 
Passing argument to method
0
 
default(T) in generic method with new() constraint
0
 
new T() in generic method with new() constraint
987
 
default(T) in generic method with struct constraint
0
 
new T() in generic method with struct constraint
0
 
Activator.CreateInstance(typeof(Structure))
0
 
Activator.CreateInstance<Structure>()
0

4. Если компилить с 987 и потом подменить на честную, бросит эксепшн что конструктор не определен

В архиве прилагаю собранные честную и 987 либы. Можно переименовать в Lib.dll и скомпилить с тестом
Вложения
Тип файла: zip Struct.zip (6.8 Кб, 0 просмотров)
1
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,176
Записей в блоге: 2
11.10.2018, 22:27
Цитата Сообщение от КОП Посмотреть сообщение
Итак, провел небольшой тест с подменой понятий dll. Вот результат. Что с ним делать я понятия не имею

Аплодирую Вашей настойчивости в поисках неизвестно чего!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
11.10.2018, 22:27

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

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
46
Ответ Создать тему
Новые блоги и статьи
GitHub Copilot в JetBrains: модель по умолчанию, Fix и контроль MCP
and_y87 12.10.2026
10 октября 2026 года GitHub обновил Copilot для JetBrains: добавил настройки стартовой модели, исправления из диагностики и управление автозапуском MCP. Поддержка IDE 2025. 1 прекращена — требуется. . .
День 5 из 28: Codex подсказывает следующий запрос
and_y87 12.10.2026
9 октября 2026 года OpenAI запустила бету Composer predictions — подсказок следующего сообщения в текущем диалоге Codex. Это помощь с формулировкой запроса, а не автоматическое продолжение задачи. . . .
Запустил конкурс "тем и промптов для текстовых квестов созданных почти чисто ИИ"
Adler 06.10.2026
Всем привет! За последние три-четыре дня я создал более 16 текстовых квестовых игр используя преимущественно по одному запросу к ИИ на игру. Мне так понравилось смотреть все ветки/ сцены во всех. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru