Форум программистов, компьютерный форум, киберфорум
Наши страницы
C# Windows Forms
Войти
Регистрация
Восстановить пароль
 
a13428711
0 / 0 / 0
Регистрация: 09.02.2016
Сообщений: 83
1

Массив констант в статическом классе. Как правильно сделать

15.08.2019, 13:51. Просмотров 218. Ответов 17
Метки нет (Все метки)

Добрый день!
Есть задача, сделать класс с данными, в котором хранится простой массив с данными и классы, содержащие массивы константных значений. Как это правильно реализовать?
Сейчас у меня это сделано вот так:
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
public class Data
{
    public static class Phase
    {
        public const int NUM = 3;
 
        public static string[] Names = {
                                            "A",
                                            "B",
                                            "C",
                                       };
 
        public static int[] Index = {
                                            0,
                                            1,
                                            2
                                     };
 
        public static int[] Adress = {
                                            0,
                                            100,
                                            200
                                     };
    }
 
 
    public static class Params
    {
        public const int NUM = 4;
 
        public static class Index_CLS
        {
            internal const int Current = 0;
            internal const int Voltage = 1;
            internal const int Active_Power = 2;
            internal const int Reactive_Power = 3;
        }
 
        public static string[] Name = {
                                            "Current",
                                            "Voltage",
                                            "Active_Power",
                                            "Reactive_Power",
                                      };
 
        public static int[] Adress = {
                                        10,
                                        Adress[Index_CLS.Current] + Bytes[Index_CLS.Current],
                                        Adress[Index_CLS.Voltage] + Bytes[Index_CLS.Voltage],
                                        Adress[Index_CLS.Active_Power] + Bytes[Index_CLS.Active_Power],
                                     };
 
        public static int[] Bytes = {
                                        4, //Current
                                        4, //Voltage
                                        8, //Active_Power
                                        8 //Reactive_Power
                                    };
    }
 
 
    public double[,] Values = new double[Params.NUM, Phase.NUM];
    public static int IUabc_BLOCK_SIZE = 152;
}
В другом классе заполняется массив Values :
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
internal void parcer(byte[] Buff, Data Data_EX)
{
    int Temp_Index = 0;
 
    for (int i = 0; i < Data.Phase.NUM; i++)
    {
        for (int Param = 0; Param < Data.Params.NUM; Param++)
        {
            Temp_Index = Data.Phase.Adress[i] + Data.Params.Adress[Param];
            Data_EX.Values[Param, i] = Buff[Temp_Index];
        }
    }
}
В другом классе эти данные используются для создания и заполнения DataGridViwe:
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
       void DGV_init()
       {
            Got_Data_DGV.ColumnCount = EnForm.Data_CLS.Phase_CLS.NUM;
            for (int i = 0; i < EnForm.Data_CLS.Phase_CLS.NUM; i++)
            {
                Got_Data_DGV.Columns[i].Name = "ertgy"; //EnForm.Data_CLS.Phase_CLS.Name[i];
                Got_Data_DGV.Columns[i].Width = CellWidth;
            }
 
            Got_Data_DGV.RowCount = EnForm.Data_CLS.Params_CLS.NUM;
            for (int i = 0; i < EnForm.Data_CLS.Params_CLS.NUM; i++)
            {
                Got_Data_DGV.Rows[i].HeaderCell.Value = "ertgy"; //EnForm.Data_CLS.Params_CLS.Name[i]; ;
                Got_Data_DGV.Rows[i].Height = CellHeight;
            }
        }
 
        public void refresh_Got_Data_DGV()
        {
            for (int Column = 0; Column < EnForm.Data_CLS.Phase_CLS.NUM; Column++)
            {
                for (int Row = 0; Row < EnForm.Data_CLS.Params_CLS.NUM; Row++)
                {
                    Got_Data_DGV.Rows[Row].Cells[Column].Value = Data_LOC.Values[Row, Column];
                }
            }
        }

Компилируется все нормально, но при заполнении таблицы в парсере возникает фатал (см. скрин)

PS на скрине код немного другой, так как я выкинул все лишние операции дабы не отвлекать вас от сути проблемы тоннами кода, но суть осталась прежняя.
0
Миниатюры
Массив констант в статическом классе. Как правильно сделать  
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
15.08.2019, 13:51
Ответы с готовыми решениями:

Как сделать видимым текст из TextBox в статическом методе?
Есть значение введенное в текстбокс. Как сделать так, чтобы это значение было видимо в статик...

Как правильно задать массив в классе Student
Добрый вечер!Подскажите, пожалуйста, как мне правильно задать массив в классе Student (в...

Как в классе правильно объявить массив с константой в качестве размерности?
Приветствую всех! Написал следующий код: Unit1.h class WireBare_Open { const int...

Ошибки в статическом классе
Есть такой вопрос. Необходимо создать статический класс MyMath, и использовать класс Math для...

Рекурсия в замещающем статическом классе
namespace Extension { static class ExtensionClass { public static void...

17
V_Monomax
1339 / 1194 / 20
Регистрация: 09.08.2011
Сообщений: 2,197
Записей в блоге: 1
Завершенные тесты: 1
15.08.2019, 14:35 2
а можно пояснение, что вы делает в форме?
0
a13428711
0 / 0 / 0
Регистрация: 09.02.2016
Сообщений: 83
15.08.2019, 14:45  [ТС] 3
В форме кнопка и DataGridViwe. Когдф нажимаем на кнопку программа получает массив байтов и передает их в парсер. Парсер их распихивает в массив Values класса Data, а затем вызывает функцию обновления данных в DataGridViwe (refresh_Got_Data_DGV), которая распихивает данные из массива Values класса Data в DataGridViwe.
0
V_Monomax
1339 / 1194 / 20
Регистрация: 09.08.2011
Сообщений: 2,197
Записей в блоге: 1
Завершенные тесты: 1
15.08.2019, 14:55 4
а зачем класс в классе?
И почему вы их делаете статичными?
0
15.08.2019, 14:55
a13428711
0 / 0 / 0
Регистрация: 09.02.2016
Сообщений: 83
15.08.2019, 14:59  [ТС] 5
Класс в классе потому что удобно обращаться: в цепочке сразу понятно какой параметр куда вкладывается.
Статичные потому, что классов Data может быть несколько, а все значения в статичных классах класса Data одинаковые и неизменяемые.
0
V_Monomax
1339 / 1194 / 20
Регистрация: 09.08.2011
Сообщений: 2,197
Записей в блоге: 1
Завершенные тесты: 1
15.08.2019, 15:33 6
Цитата Сообщение от a13428711 Посмотреть сообщение
public static string[] Names = {
"A",
"B",
"C",
};
public static int[] Index = {
0,
1,
2
};
public static int[] Adress = {
0,
100,
200
};
в данном случае использовать enum:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
enum PhaseNames
{
A,
B,
C,
}
 
enum Index 
{
 0,
 1,
 2
 }
enum Adress
{
 0,
 100,
 200
}
и ни какого класса не надо...

Добавлено через 7 минут
в общем-то вы что-то делаете не верно в корне, и сами себе придумываете препятствия, можно использовать вообще словарик... Не нужны вам в данном случае никакие статические классы (которые к тому-же создают вам проблемы). Любую справочную информацию, хранят либо в перечислениях (enum) либо в словарях (Dictonary)

Добавлено через 6 минут
Самое интересно, что вы не дали полной информации, чему равны i, Param!

Добавлено через 7 минут
Цитата Сообщение от a13428711 Посмотреть сообщение
Класс в классе потому что удобно обращаться
Очень не удобно:
1. вы засираете память, так как все потомки будут живы до тех пор пока вы не отключите программу (по сути статик классом вы создаете утечку памяти).
2. Вы уже запутались в собственном коде и не понимаете почему.
3. Справочные данные, всегда хранятся в настройках, в бл, в файлах, и в общем-то ни к чему их таскать в программе.
4. удобнее написать инициализатор принимающий нужный набор из перечислителей, пусть это будет даже бледная модель данных
5. Такого, да и вообще статик данных старательно избегают, потому как статик данные часто поражадают утечки памяти, которые потом не отследить и не вычислить.
Исходя из сказаного я бы на вашем месте переделал бы все иначе, но вопрос только к вам готовы ли вы сломать свою концепцию построения кода. и принять уже существующую, и успешно работающую концепцию S.O.L.I.D.?
0
a13428711
0 / 0 / 0
Регистрация: 09.02.2016
Сообщений: 83
15.08.2019, 16:06  [ТС] 7
А если значения для перечисления нужно получать как тут, то как быть?
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
public static class Index_CLS
        {
            internal const int Current = 0;
            internal const int Voltage = 1;
            internal const int Active_Power = 2;
            internal const int Reactive_Power = 3;
        }
 
        public static string[] Name = {
                                            "Current",
                                            "Voltage",
                                            "Active_Power",
                                            "Reactive_Power",
                                      };
 
        public static int[] Adress = {
                                        10,
                                        Adress[Index_CLS.Current] + Bytes[Index_CLS.Current],
                                        Adress[Index_CLS.Voltage] + Bytes[Index_CLS.Voltage],
                                        Adress[Index_CLS.Active_Power] + Bytes[Index_CLS.Active_Power],
                                     };
 
        public static int[] Bytes = {
                                        4, //Current
                                        4, //Voltage
                                        8, //Active_Power
                                        8 //Reactive_Power
                                    };
0
V_Monomax
1339 / 1194 / 20
Регистрация: 09.08.2011
Сообщений: 2,197
Записей в блоге: 1
Завершенные тесты: 1
15.08.2019, 16:43 8
Цитата Сообщение от a13428711 Посмотреть сообщение
public static int[] Adress = {
10,
Adress[Index_CLS.Current] + Bytes[Index_CLS.Current],
Adress[Index_CLS.Voltage] + Bytes[Index_CLS.Voltage],
Adress[Index_CLS.Active_Power] + Bytes[Index_CLS.Active_Power],
};
Для начала объясните что это?
Зачем идет ссылка на самого себя???
по сути вы в массиве указываете, не числа, а вычисляете их, зачем?
по сути,
Цитата Сообщение от a13428711 Посмотреть сообщение
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
public static class Index_CLS
 {
 internal const int Current = 0;
 internal const int Voltage = 1;
 internal const int Active_Power = 2;
 internal const int Reactive_Power = 3;
 }
public static string[] Name = {
 "Current",
 "Voltage",
 "Active_Power",
 "Reactive_Power",
 };
public static int[] Adress = {
 10,
 Adress[Index_CLS.Current] + Bytes[Index_CLS.Current],
 Adress[Index_CLS.Voltage] + Bytes[Index_CLS.Voltage],
 Adress[Index_CLS.Active_Power] + Bytes[Index_CLS.Active_Power],
 };
public static int[] Bytes = {
 4, //Current
 4, //Voltage
 8, //Active_Power
 8 //Reactive_Power
};
можно успешно заменить на
C#
1
public static int[] Adress = {10,14,18,26};
И не надо никаких вычислений!
Если вам нужно что-бы массив заполнялся чем-то, и отрабатывала некоторая логика, то для этого должен быть отдельный метод.
0
a13428711
0 / 0 / 0
Регистрация: 09.02.2016
Сообщений: 83
15.08.2019, 16:50  [ТС] 9
Я хочу чтоб вычисление происходило один раз при компиляции, чтобы это не отнимало лишние ресурсы при запуске программы.
Вычисления нужны, так как есть вероятность, что со временем будут добавляться дополнительные поля. При таком подходе не придется потом все адреса вручную пересчитывать.
0
V_Monomax
1339 / 1194 / 20
Регистрация: 09.08.2011
Сообщений: 2,197
Записей в блоге: 1
Завершенные тесты: 1
15.08.2019, 16:53 10
Цитата Сообщение от a13428711 Посмотреть сообщение
Я хочу чтоб вычисление происходило один раз при компиляции, чтобы это не отнимало лишние ресурсы при запуске программы.
Цитата Сообщение от V_Monomax Посмотреть сообщение
public static int[] Adress = {10,14,18,26};
вообще,не занимает ресурсов вычисления!
А вот ваш вариант, будет занимать статичные (в размеченной памяти) данные, да еще и при каждом вызове класса производить вычисления! Так что здесь вы тратитесь, кроме того по сложности вычислений, хм, сигнал от мозга до глаза, что ему надо моргнуть, не успеет дойти, а вычисления будут сделаны. Так что то что вы пишите фигня, да еще и на постном масле!
0
a13428711
0 / 0 / 0
Регистрация: 09.02.2016
Сообщений: 83
15.08.2019, 16:57  [ТС] 11
Но ваш вариант тяжело расширить. К примеру у меня будет сотня таких адресов, а затем понадобится добавить один адрес в самом начале (адреса начинаются не с нуля) и придется пересчитывать все 100 адресов ручками. Основная причина в этом.
0
V_Monomax
1339 / 1194 / 20
Регистрация: 09.08.2011
Сообщений: 2,197
Записей в блоге: 1
Завершенные тесты: 1
15.08.2019, 16:59 12
Цитата Сообщение от a13428711 Посмотреть сообщение
Вычисления нужны, так как есть вероятность, что со временем будут добавляться дополнительные поля.
тогда, это делается в отдельном методе, и что при каждом изменении перекомпилировать файл? Фигня! Надо тогда такие вещи выносить в settings, и там их хранить, а при вызове программного кода получать их оттуда! Делается вообще легко! Занимает малое время при работе (как вариант, вообще вытаскивать в некоторое значение в управляемой куче, при вызове метода).

Добавлено через 1 минуту
Цитата Сообщение от a13428711 Посмотреть сообщение
Но ваш вариант тяжело расширить
легко! Просто создается файл настроек, и туда пишуться все нужные данные, а затем при запуске программы(лучше при вызове класса) считываются данные из настроек, и при этом ничего не надо перекомпилировать.

Добавлено через 1 минуту
Цитата Сообщение от a13428711 Посмотреть сообщение
К примеру у меня будет сотня таких адресов, а затем понадобится добавить один адрес в самом начале (адреса начинаются не с нуля)
легко, для этого делается отдельный класс, который работает с настройками и соответствующим образом их правит.
1
a13428711
0 / 0 / 0
Регистрация: 09.02.2016
Сообщений: 83
15.08.2019, 17:03  [ТС] 13
Но новые значения ({10,14,18,26}) в файл настоек придется вбить ручками.

Добавлено через 1 минуту
Цитата Сообщение от V_Monomax Посмотреть сообщение
легко, для этого делается отдельный класс, который работает с настройками и соответствующим образом их правит.
Но класс при каждом запуске будет из высчитывать. А тут у меня в статике хранятся готовые значения, вычисленные при компиляции. Или я что-то не догоняю?

Добавлено через 1 минуту
Мне нужен один экземпляр массива констант, вычисляемый однократно при компиляции.
0
V_Monomax
1339 / 1194 / 20
Регистрация: 09.08.2011
Сообщений: 2,197
Записей в блоге: 1
Завершенные тесты: 1
15.08.2019, 17:11 14
так что вы делаете не правильно!
тут можно пройти множество путей, как ввести собственный файл с настройками, так и просто использовав настройки внедренные в приложение.

Добавлено через 1 минуту
Цитата Сообщение от a13428711 Посмотреть сообщение
Но класс при каждом запуске будет из высчитывать.
допустим
Цитата Сообщение от a13428711 Посмотреть сообщение
А тут у меня в статике хранятся готовые значения, вычисленные при компиляции.
очень сильно заблуждаетесь, потому как они будут именно высчитываться, да и еще при каждом вызове класса.
Цитата Сообщение от a13428711 Посмотреть сообщение
Мне нужен один экземпляр массива констант, вычисляемый однократно при компиляции.
при компиляции не происходит никаких вычислений!

Добавлено через 1 минуту
Цитата Сообщение от a13428711 Посмотреть сообщение
Но новые значения ({10,14,18,26}) в файл настоек придется вбить ручками.
почему?
Если вы вводите файл настроек, то их можно менять при помощи вашей же программы, но только в другом окне, и о чудо, можно даже и не отключать программу!))
1
a13428711
0 / 0 / 0
Регистрация: 09.02.2016
Сообщений: 83
16.08.2019, 09:40  [ТС] 15
Цитата Сообщение от V_Monomax Посмотреть сообщение
при компиляции не происходит никаких вычислений!
Вы хотите сказать, что если у меня будет выражение, состоящее из константных значений (например int a = 2+3+7), то
компилятор не пропишет число 12 вместо него?

Добавлено через 2 минуты
Цитата Сообщение от V_Monomax Посмотреть сообщение
Если вы вводите файл настроек, то их можно менять при помощи вашей же программы, но только в другом окне, и о чудо, можно даже и не отключать программу!))
Просто тут из настроек только эти массивы, и не хотелось бы ради них создавать отдельный файл, который еще и при переносе программы могут потерять где-то. А так есть один экзешник и всё.
0
V_Monomax
1339 / 1194 / 20
Регистрация: 09.08.2011
Сообщений: 2,197
Записей в блоге: 1
Завершенные тесты: 1
16.08.2019, 09:48 16
Цитата Сообщение от a13428711 Посмотреть сообщение
компилятор не пропишет число 12 вместо него?
нет, компилятор пропишет совершать операцию сложения между этими числами.
Цитата Сообщение от a13428711 Посмотреть сообщение
Просто тут из настроек только эти массивы, и не хотелось бы ради них создавать отдельный файл, который еще и при переносе программы могут потерять где-то. А так есть один экзешник и всё.
Хорошо, допустим, что потеряют, но это проблема тех кто переносит. Другой вопрос, зачем перекомпилировать проект каждый раз при внесении новых параметров?

Добавлено через 3 минуты
с другой стороны у разных пользователей может быть необходимость разных настроек... И тут вам только отсечь не нужное...
0
a13428711
0 / 0 / 0
Регистрация: 09.02.2016
Сообщений: 83
16.08.2019, 09:58  [ТС] 17
Цитата Сообщение от V_Monomax Посмотреть сообщение
нет, компилятор пропишет совершать операцию сложения между этими числами
Не знал. Странно как-то. Спасибо за информацию, тогда можно не париться и просто сделать отдельный метод для хранения массивов в виде переменных и реализовать только чтение интерфейсом. Правильный подход будет?
Цитата Сообщение от V_Monomax Посмотреть сообщение
Хорошо, допустим, что потеряют, но это проблема тех кто переносит.
В моем случае это будет и моей проблемой)
0
V_Monomax
1339 / 1194 / 20
Регистрация: 09.08.2011
Сообщений: 2,197
Записей в блоге: 1
Завершенные тесты: 1
16.08.2019, 10:12 18
Цитата Сообщение от a13428711 Посмотреть сообщение
Не знал. Странно как-то.
ничего странного, компилятор не выполняет операций вашей программы, он только перестраивает код в текстовую структуру, а вот уже виртуальная машина, при исполнении производит все расчеты. При этом следует учитывать как работает сборщик мусора. А сборщик мусора, работает по принципу: нет ссылок на сущность(класс), я его приберу, есть ссылки, значит убирать не буду. Следовательно, в вашем случае возникает статик сущность, и остальные сущности, при этом остальные сущности (то что вы создаете с ключевым словом new), ссылаются на статик сущность, а статик сущность ссылается на все сущности в управляемой куче. Таким образом, при работе программы, происходит заполнение оперативной памяти, но не происходит ее высвобождения, так до стаковерфлов не далеко! А следовательно вы получаете ситуацию с неизвестным окончанием (засорением оперативной памяти и последующим "подвисанием" компьютера).
Цитата Сообщение от a13428711 Посмотреть сообщение
В моем случае это будет и моей проблемой)
В чем проблема хранить файл настроек?
0
16.08.2019, 10:12
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
16.08.2019, 10:12

Однопоточный таймер в статическом классе
Здравствуйте. Возник вопрос: у меня есть класс, в нем мне нужен таймер, чтобы работал в вызывающем...

Нестатический метод в статическом классе
Возник вопрос, есть такого рода пример: static class staticClass { public void...

Сделать массив констант, содержащий символы от '0' до '9' и от 'A' до 'Z'
Как в С++ сделать массив констант, содержащий символы от 0 до 9 и от A до Z


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

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

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