Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.97/30: Рейтинг темы: голосов - 30, средняя оценка - 4.97
 Аватар для dimakozyr
383 / 30 / 3
Регистрация: 17.08.2013
Сообщений: 560

Как передать двумерный массив в другой класс

08.02.2014, 00:59. Показов 6509. Ответов 23
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть двумерный массив:
C#
1
2
    private bool[ , ] aUniverse = new bool[(int)UNIVERSE_SIZE.HEIGTH, (int)UNIVERSE_SIZE.WIDTH];
    private enum UNIVERSE_SIZE { HEIGTH = 10, WIDTH = 10 }
А так-же Get для переменных массива:
C#
1
2
3
4
5
public int GUniverseSizeHeigth
        { get { return (int)UNIVERSE_SIZE.HEIGTH; } }
 
public int GUniverseSizeWidth
        { get { return (int)UNIVERSE_SIZE.WIDTH; } }
Как мне передать сам массив в другой класс?
И правильно-ли это - передавать массив?

Вопрос вдогонку, как мне сделать, чтоб при использовании перечислений не нужно было явно тип указывать, как у меня "int"?
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
08.02.2014, 00:59
Ответы с готовыми решениями:

Как передать массив в другой класс
Не могу понять, я хочу чтобы массив заполнялся в классе Program а выводился в классе Clas методе Out. Но чтобы не пытался изменить...

Как передать в функцию двумерный массив указателей на класс?
у меня есть std::vector<Monster*> monsters; Rect *pole; int pacmen_distance; Monster и Rect два...

Как считанный из файла массив передать в другой класс?
Дело в том, что если я просто создаю массив и заполняю его, то он у меня передаётся, а если считанный из файла то не хочет. Точнее мне надо...

23
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
08.02.2014, 01:20
А почему неправильно, если Вы хотите инкапсулировать класс и другую часть программы. Часто так делаю, правда у меня листы, с байтами.
Или же работайте через параметр типа ref - out.
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
08.02.2014, 09:29
dimakozyr, перечисления не для этого созданы, е-мое.
const int Width = 10 чем не устраивает?

Массив передать: а что в этом криминального, чем он лучше/хуже любого другого класса?
0
 Аватар для dimakozyr
383 / 30 / 3
Регистрация: 17.08.2013
Сообщений: 560
09.02.2014, 00:29  [ТС]
Цитата Сообщение от insite2012 Посмотреть сообщение
Или же работайте через параметр типа ref - out.
А можно поподробней?

Цитата Сообщение от Psilon Посмотреть сообщение
перечисления не для этого созданы, е-мое.
const int Width = 10 чем не устраивает?
Можно и так, но я думал, что это не имеет большого значения, часто так делаю
0
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
09.02.2014, 00:54
Лучший ответ Сообщение было отмечено dimakozyr как решение

Решение

Цитата Сообщение от dimakozyr Посмотреть сообщение
А можно поподробней?
А что тут подробнее-то... Передаете в метод какого-то класса массив с параметром ref (или out, смотря как инициализировать), и он после отработки метода уже заполнен данными... Сейчас покажу пример...

Добавлено через 6 минут
Если в самом простом варианте, то как-то так...
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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] y = new int[1000];
            res(ref y);
            foreach (int i in y)
                Console.WriteLine(y[i]);
            Console.ReadLine();
        }
        static void res(ref int[]mass)
        {
            for (int i = 0; i < 1000; i++)
                mass[i] = i;
        }
    }
}
1
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
09.02.2014, 03:24
insite2012, можно спокойно убрать ref, код останется рабочим.

dimakozyr, enum нужно, для того, чтобы определять перечисления, я не хранить константы. Это не С++, е-мое. Там все используется для всего, была бы возможность. Хотя хорошие плюсисты тоже понимают, что для всего есть свои стредства, и использовать энумы вместо констант - это просто мерзко и ужасно. Даже хуже, чем дефайны.
1
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
09.02.2014, 10:28
Цитата Сообщение от Psilon Посмотреть сообщение
insite2012, можно спокойно убрать ref, код останется рабочим.
Это да, так это же простой пример... Был бы это другой класс, он бы уже перестал быть рабочим...
0
Эксперт .NET
 Аватар для Casper-SC
4434 / 2094 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
09.02.2014, 10:31
Цитата Сообщение от insite2012 Посмотреть сообщение
Передаете в метод какого-то класса массив с параметром ref (или out, смотря как инициализировать), и он после отработки метода уже заполнен данными...
ref нужен для передачи ссылки по ссылке. С использованием ref можно создать сам массив внутри метода и после выхода из метода массив останется принициализированным, а заполнен он или нет - это другой вопрос, вся суть в создании нового объекта внутри метода. Единственное отличие out - это то, что сама ссылка перед передачей её в метод в качестве параметра метода может быть не проинициализирована даже null(ом) и после выхода из метода она должна быть проинициализирована в любом случае.

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
using System;
using System.IO;
 
namespace ConsApp_RefOut
{
    class Program
    {
        static void Main(string[] args)
        {
            Person person1 = new Person() { Age = 18, Name = "Изначально созданный" };
            Console.WriteLine("Вызываем метод: GetPersonWithoutRefOrOut");
 
            //Созданный объект внутри метода "так и останется внутри метода"
            GetPersonWithoutRefOrOut(person1); 
            Console.WriteLine("Результат его работы:");
            Console.WriteLine(person1);
            Console.WriteLine("Как видно созданный объект внутри метода не передался" +
                " за его пределы, так как на него ссылалась копия ссылки Person\n");
 
            Person person2;
 
            GetPersonRef(ref person1); //передаём уже проинициализированную ссылку
            GetPersonOut(out person2); //передаём НЕ проинициализированную ссылку
 
            Console.WriteLine(person1);
            Console.WriteLine(person2);
 
            string text; //нет смысла инициализировать, только для передачи в метод
            if (TryReadText(out text, "Бла-бла-бла"))
                Console.WriteLine(Environment.NewLine + text);
            else
                Console.WriteLine(Environment.NewLine + "Текст не удалось прочитать");
 
            Console.ReadKey();
        }
 
        public static bool TryReadText(out string text, string filePath)
        {
            if (File.Exists(filePath))
            {
                text = File.ReadAllText(filePath);
                return true;
            }
            text = string.Empty;
            return false;
        }
 
        //передаётся копия ссылки Person
        public static void GetPersonWithoutRefOrOut(Person person)
        {
            person = new Person { Age = 90, Name = "Из метода GetPersonWithoutRefOrOut" };
        }
 
        //передаётся ссылка по ссылке, но передаваемая ссылка
        //должна быть инициализирована хотя бы null
        public static void GetPersonRef(ref Person person)
        {
            person = new Person { Age = 20, Name = "Из метода ref" };
        }
 
        //передаётся ссылка по ссылке, но передаваемая ссылка
        //может быть не инициализирована
        public static void GetPersonOut(out Person person) 
        {
            person = new Person { Age = 30, Name = "Из метода out" };
        }
    }
}
C#
1
2
3
4
5
6
7
8
9
10
    public class Person
    {
        public override string ToString()
        {
            return string.Format("Возраст: {0} Имя: {1}", Age, Name);
        }
 
        public string Name { get; set; }
        public uint Age { get; set; }
    }
И да, использовать enum для хранения константных значений - ересь ИМХО. Чем не проще создать отдельный класс с константами. Если нужна вложенносить для удобства чтения, то внтури этого класса создай ещё оин класс и будет тебе тоже самое.

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    /// <summary>
    /// Хранит константы
    /// </summary>
    public static class Constants
    {
        /// <summary>
        /// Универсальный размер чего-то там или для чего-то...
        /// </summary>
        public static class UNIVERSE_SIZE
        {
            /// <summary>Ширина</summary>
            public const int WIDTH = 100;
 
            /// <summary>Высота</summary>
            public const int HEIGHT = 200;
        }
    }
C#
1
int height = Constants.UNIVERSE_SIZE.HEIGHT;
Добавлено через 56 секунд
Цитата Сообщение от insite2012 Посмотреть сообщение
Был бы это другой класс, он бы уже перестал быть рабочим...
Покажи на примере, где он перестанет работать. Всё там также будет работать, я тебе заранее скажу.
1
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
09.02.2014, 10:50
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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            myclass mc = new myclass();
            int i=0;
            string s1=null;
            string s2=null;
            Console.WriteLine("Первоначальные значения:");
            Console.WriteLine("{0}, {1}, {2}", i, s1, s2);
 
            //Метод класса, возвращающий по ссылке три значения
            mc.method(out i, out s1, out s2);
            Console.WriteLine("Новые значения:");
            Console.WriteLine("{0}, {1}, {2}", i, s1, s2);
            Console.ReadLine();
        }
    }
    class myclass
    {
        public void method(out int i, out string str1, out string str2)
        {
            i = 44;
            str1 = "Строка 1";
            str2 = "Строка 2";
        }
    }
}
1
Эксперт .NET
 Аватар для Casper-SC
4434 / 2094 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
09.02.2014, 11:19
Ты показал в точности то, что я и рассказал выше. Создать массив и заполнить его - разные вещи. В общем, твой код показывает тоже самое, что выше мой.

Добавлено через 9 минут
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
using System;
 
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] arr;
            Tester.CreateArray(out arr);
            Display("Tester.CreateArray(out arr);", arr);
 
            Tester.CreateArray(arr);
            Display("\r\nTester.CreateArray(arr);", arr);
 
            Console.ReadKey();
        }
 
        public static void Display(string message, string[] arr)
        {
            Console.WriteLine(message);
            foreach (string text in arr)
            {
                Console.Write(text);
            }
            Console.WriteLine();
        }
    }
 
    public static class Tester
    {
        public static void CreateArray(out string[] arr)
        {
            arr = new string[] { "Я был ", "создан внутри метода ", " с out параметром" };
        }
 
        public static void CreateArray(string[] arr)
        {
            arr = new string[] { "Этот текст ", "ты всё равно ", "не увидишь" };
        }
    }
}
Добавлено через 4 минуты
А вот тебе заполение массива в методах с out и без
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
using System;
 
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] arr = new string[3];
            Tester.FillArray(out arr);
            Display("Tester.FillArray(out arr);", arr);
 
            Tester.FillArray(arr);
            Display("\r\nTester.FillArray(arr);", arr);
 
            Console.ReadKey();
        }
 
        public static void Display(string message, string[] arr)
        {
            Console.WriteLine(message);
            foreach (string text in arr)
            {
                Console.Write(text);
            }
            Console.WriteLine();
        }
    }
 
    public static class Tester
    {
        public static void FillArray(out string[] arr)
        {
            arr = new string[3]; //из-за out просто придётся создавать массив внутри
            arr[0] = "Я был ";
            arr[1] = "создан и заполнен внутри метода ";
            arr[2] = "с ключевым словом out";
        }
 
        public static void FillArray(string[] arr)
        {
            arr[0] = "Я был "; //выглядит не очень, но для примера сойдёт
            arr[1] = "заполнен внутри метода ";
            arr[2] = "БЕЗ ключевого слова out";
        }
    }
}
1
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
09.02.2014, 11:26
Цитата Сообщение от Casper-SC Посмотреть сообщение
Ты показал в точности то, что я и рассказал выше. Создать массив и заполнить его - разные вещи. В общем, твой код показывает тоже самое, что выше мой.
Так понятно, что мы говорим об одном и том же...
Я такой прием часто использую, когда в классе есть метод, возвращающий строку - результат операции, успешно или нет. Но кроме этого этот же метод должен еще и вернуть мне массив байт, вот я и использую для возврата нужных мне данных ссылочный параметр...
0
Эксперт .NET
 Аватар для Casper-SC
4434 / 2094 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
09.02.2014, 11:28
Цитата Сообщение от insite2012 Посмотреть сообщение
когда в классе есть метод, возвращающий строку - результат операции, успешно или нет. Но кроме этого этот же метод должен еще и вернуть мне массив байт
А bool уже не в моде? Возвращать результат операции в строке? Покажи пример, может я не так себе это представляю?
0
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
09.02.2014, 11:44

Не по теме:

Понятно, что и bool нормально. Но дело в том, что строка возврата может быть разная.
Ну вот пример. В классе есть метод, записывает данные в порт, потом их же считывает, и сравнивает. Так вот, если делать с возвратом только bool, то я не смогу точно узнать, где возникла проблема, просто буду видеть, успешно/не успешно прошла операция. А вот с возвратом строки я всегда вижу, где что-то пошло не так... К примеру, запись прошла нормально, а при считывании проблемы. Так вот вернется строка "Ошибка при проверочном чтении". Проблемы при сравнении - вернется другая строка. И так далее. И в исключении тоже идет возврат строки, какое исключение возникло. А в основной программе этот метод идет как параметр мессаджа.



Добавлено через 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
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
       //Метод записи данных в модуль
        public string WriteModule(List<byte> datawrite)
        {
            byte[] mcuaccess = { 0xa5, 0xee, 0x02, 0x93, 0x10, 0x05, 0x0c, 0x10, 0xf1, 0xf1, 0x00, 0x3b };
            byte[] wpoff = { 0xa5, 0xee, 0x2, 0x93, 0x20, 0x5, 0xc, 0x20, 0x0, 0xdb, 0x0, 0x54 };
            byte[] wpon = { 0xa5, 0xee, 0x2, 0x93, 0x20, 0x5, 0xc, 0x20, 0x0, 0x0, 0x0, 0x79 };
            byte[] writeblock = { 0xa5, 0xee, 0x2, 0x91, 0x40, 0x23, 0xa0, 0x00, 0x00 };
            
            //Переворот байтов во входном массиве(данные загружаются как bin,
            //запись всегда в формате eep)
            datawrite = EepToBin(datawrite);
 
            //**********Старт процесса записи в модуль**********
            using (port)
            {
                port.Open();
 
                try
                {
                    //Попытка соединения с устройством
                    int i=0;
                    while(i <=10)
                    {
                        port.DiscardInBuffer();
                        //Запрос в порт
                        for(int j = 0;j < mcuaccess.Length; j++){
                            port.Write(mcuaccess, j, 1);
                        }
                        bool flag = false;
                        //Ожидание заполнения буфера порта
                        for (int j = 0; j <= 100; j++)
                        {
                            if (port.BytesToRead == 9)
                            {
                                ReadData(9);
                                flag = true;//Флаг успешного чтения
                                break;
                            }
                            else
                                Thread.Sleep(5);
                        }
                        i++;
                        //Условие выхода
                        if (i >= 10)
                            return "Устройство не отвечает!";
                        if (flag)
                            break;
                        else
                            Thread.Sleep(500);
                    }
 
                    //Отключение WP
                    for (int n = 0; n < wpoff.Length; n++){
                        port.Write(wpoff, n, 1);
                    }
                    //Ожидание заполнения буфера порта
                    for (int j = 0; j <= 100; j++)
                    {
                        if (port.BytesToRead == 1)
                        {
                            ReadData(1);
                            break;
                        }
                        else
                            Thread.Sleep(10);
                        if (j == 10)
                            return "Устройство не отвечает!";
                    }
                    //**********Окончание блока преварительного запроса**********
 
                    //Событие включения прогрессбара
                    if (baron != null)
                        baron();
 
                    //**********Основной блок записи**********
 
                    byte[] datablock = new byte[33];//Массив блока данных
                    int blocklen = 0x20;//Размер блока записи
                    int shiftindex = 0;//Индекс сдвига по массиву загр.данных
                    int datalength = datawrite.Count;//Размер загруженных данных
 
                    //Основной цикл записи
                    do
                    {
                        //Заполнение блока данных(размер блока-стандарт, 0x20)
                        if (blocklen == 0x20)
                        {
                            for (int d = 0; d < blocklen; d++)
                            {
                                datablock[d] = datawrite[d + shiftindex];
                            }
                        }
                        else
                        {
                            //Заполнение блока данных про остатке данных < 0х20,
                            //Оставшаяся часть заполняется 0x00
                            for (int d = 0; d < blocklen; d++)
                            {
                                datablock[d] = datawrite[d + shiftindex];
                            }
                            for (int g = blocklen; g < 0x20; g++)
                            {
                                datablock[g] = 0x00;
                            }
                        }
                        //Сброс КС 
                        datablock[datablock.Length - 1] = 0;
                        //Просчет КС обоих блоков (записи и данных)
                        datablock[datablock.Length - 1] = (byte)((writeblock.Sum(n => (int)n)) +
                                                                 (datablock.Sum(n => (int)n)));
 
                        //Запись в порт блока запроса и блока данных
                        for (int w1 = 0; w1 < writeblock.Length; w1++)
                        {
                            port.Write(writeblock, w1, 1);
                        }
                        for (int w2 = 0; w2 < datablock.Length; w2++)
                        {
                            port.Write(datablock, w2, 1);
                        }
                        
 
                        //Ожидание заполнения буфера порта
                        for (int j = 0; j <= 10; j++)
                        {
                            if (port.BytesToRead == 1)
                            {
                                ReadData(1);//Прием ответа подтверждения
                                break;
                            }
                            else
                                Thread.Sleep(200);//Возможно потребуется коррекция задержки!!!
                            if (j == 10)          //******************************************
                            {
                                //Отключение прогрессбара
                                if (baroff != null)
                                    baroff();
                                return "Ошибка при записи!";
                            }
                        }
 
                        //Изменение адресов в запросе
                        writeblock[7] = (byte)((writeblock[7] + 0x10) & 0xff);
                        if (writeblock[7] == 0)
                            writeblock[8] += 1;
 
                        
                        //Уменьшение общ.размера на размер блока записи
                        datalength -= blocklen;
                        //Изменение индекса сдвига по массиву загр.данных
                        if (datalength < 0x20)
                        {
                            shiftindex += datalength;//Увеличение индекса сдвига
                            blocklen = datalength;   //Изменение размера блока записи
                        }
                        else
                        {
                            shiftindex += 0x20;//Увеличение индекса сдвига
                        }
                        //Событие прогресса при записи
                        if (barwrite != null)
                            barwrite();
 
                        //Обработка сообщений
                        Application.DoEvents();
                    }
                    while (datalength!=0);//Выход при нулевом размере загруженных данных
 
                    //Событие сброса прогресса
                    if (barclear != null)
                        barclear();
 
                    //**********Окончание записи в модуль**********
 
                    //Проверочное чтение
                    List<byte> dataread = new List<byte>();
                    if (!writecheck(ref dataread))
                    {
                        //Отключение прогрессбара
                        if (baroff != null)
                            baroff();
                        return "Ошибка при проверочном чтении!";
                    }
                        
 
                    //Проверочное сравнение
                    if (!datacompare(dataread, datawrite))
                    {
                        //Отключение прогрессбара
                        if (baroff != null)
                            baroff();
                        return "Ошибка сравнения данных!";
                    }
                        
 
                    //Включение WP
                    for (int wp = 0; wp < wpon.Length; wp++)
                    {
                        port.Write(wpon, wp, 1);
                    }
                    //Ожидание заполнения буфера порта
                    for (int j = 0; j <= 100; j++)
                    {
                        if (port.BytesToRead == 1)
                        {
                            ReadData(1);//Прием ответа подтверждения
                            break;
                        }
                        else
                            Thread.Sleep(100);
                        if (j == 100)
                        {
                            //Отключение прогрессбара
                            if (baroff != null)
                                baroff();
                            return "Устройство не отвечает!";
                        }
      
                    }
                }
                catch(Exception ex)
                {
                    //Отключение прогрессбара
                    if (baroff != null)
                        baroff();
                    return "Ошибка при записи"+"\n"+ ex.Message;
                }
            }
            //Отключение прогрессбара
            if (baroff != null)
                baroff();
            return "Запись прошла успешно";
        }

0
Эксперт .NET
 Аватар для Casper-SC
4434 / 2094 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
09.02.2014, 13:09
Вот это методище

Его как минимум можно разбить на отдельные действия (методы) с устройством. Все ошибки должны генерировать исключения, а метод возвращать true либо false, это на первый взгляд, в код сильно не вникал и не пытался его разбить на отдельные методы.
0
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
09.02.2014, 13:35
Это только его часть.
Там внутри метода еще пара стоит, чтение и проверка после записи. А разбивать не стоит, он на первый взгляд большой, потому что много комментариев, если все их убрать, будет короче. Да и действие тут всего одно, запись данных в контроллер электронного модуля через последовательный порт.
Вы считаете, что такой способ возврата значения метода некорректен? Мне показалось это оптимальным вариантом, чтобы в основной программе не вызывать много методов с проверкой возврата каждого, а вызвать один и по строке возврата знать, как метод отработал...
Вот этот класс целиком. Только не удивляйтесь.

Не по теме:


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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
using System.Threading;
using System.Windows.Forms;
 
namespace EVO_2_Checker_v1._0._0._0
{
    class WriteClass
    {
        SerialPort port;//Экземпляр порта
        
        //События
        public event Action barwrite;
        public event Action barread;
        public event Action barclear;
        public event Action baron;
        public event Action baroff;
 
        //Конструктор
        public WriteClass(string portName)
        {
            port = new SerialPort();
            port.PortName = portName;
            port.BaudRate = 38400;
            port.ReadTimeout = 600;
        }
 
        //Метод записи данных в модуль
        public string WriteModule(List<byte> datawrite)
        {
            byte[] mcuaccess = { 0xa5, 0xee, 0x02, 0x93, 0x10, 0x05, 0x0c, 0x10, 0xf1, 0xf1, 0x00, 0x3b };
            byte[] wpoff = { 0xa5, 0xee, 0x2, 0x93, 0x20, 0x5, 0xc, 0x20, 0x0, 0xdb, 0x0, 0x54 };
            byte[] wpon = { 0xa5, 0xee, 0x2, 0x93, 0x20, 0x5, 0xc, 0x20, 0x0, 0x0, 0x0, 0x79 };
            byte[] writeblock = { 0xa5, 0xee, 0x2, 0x91, 0x40, 0x23, 0xa0, 0x00, 0x00 };
            
            //Переворот байтов во входном массиве(данные загружаются как bin,
            //запись всегда в формате eep)
            datawrite = EepToBin(datawrite);
 
            //**********Старт процесса записи в модуль**********
            using (port)
            {
                port.Open();
 
                try
                {
                    //Попытка соединения с устройством
                    int i=0;
                    while(i <=10)
                    {
                        port.DiscardInBuffer();
                        //Запрос в порт
                        for(int j = 0;j < mcuaccess.Length; j++){
                            port.Write(mcuaccess, j, 1);
                        }
                        bool flag = false;
                        //Ожидание заполнения буфера порта
                        for (int j = 0; j <= 100; j++)
                        {
                            if (port.BytesToRead == 9)
                            {
                                ReadData(9);
                                flag = true;//Флаг успешного чтения
                                break;
                            }
                            else
                                Thread.Sleep(5);
                        }
                        i++;
                        //Условие выхода
                        if (i >= 10)
                            return "Устройство не отвечает!";
                        if (flag)
                            break;
                        else
                            Thread.Sleep(500);
                    }
 
                    //Отключение WP
                    for (int n = 0; n < wpoff.Length; n++){
                        port.Write(wpoff, n, 1);
                    }
                    //Ожидание заполнения буфера порта
                    for (int j = 0; j <= 100; j++)
                    {
                        if (port.BytesToRead == 1)
                        {
                            ReadData(1);
                            break;
                        }
                        else
                            Thread.Sleep(10);
                        if (j == 10)
                            return "Устройство не отвечает!";
                    }
                    //**********Окончание блока преварительного запроса**********
 
                    //Событие включения прогрессбара
                    if (baron != null)
                        baron();
 
                    //**********Основной блок записи**********
 
                    byte[] datablock = new byte[33];//Массив блока данных
                    int blocklen = 0x20;//Размер блока записи
                    int shiftindex = 0;//Индекс сдвига по массиву загр.данных
                    int datalength = datawrite.Count;//Размер загруженных данных
 
                    //Основной цикл записи
                    do
                    {
                        //Заполнение блока данных(размер блока-стандарт, 0x20)
                        if (blocklen == 0x20)
                        {
                            for (int d = 0; d < blocklen; d++)
                            {
                                datablock[d] = datawrite[d + shiftindex];
                            }
                        }
                        else
                        {
                            //Заполнение блока данных про остатке данных < 0х20,
                            //Оставшаяся часть заполняется 0x00
                            for (int d = 0; d < blocklen; d++)
                            {
                                datablock[d] = datawrite[d + shiftindex];
                            }
                            for (int g = blocklen; g < 0x20; g++)
                            {
                                datablock[g] = 0x00;
                            }
                        }
                        //Сброс КС 
                        datablock[datablock.Length - 1] = 0;
                        //Просчет КС обоих блоков (записи и данных)
                        datablock[datablock.Length - 1] = (byte)((writeblock.Sum(n => (int)n)) +
                                                                 (datablock.Sum(n => (int)n)));
 
                        //Запись в порт блока запроса и блока данных
                        for (int w1 = 0; w1 < writeblock.Length; w1++)
                        {
                            port.Write(writeblock, w1, 1);
                        }
                        for (int w2 = 0; w2 < datablock.Length; w2++)
                        {
                            port.Write(datablock, w2, 1);
                        }
                        
 
                        //Ожидание заполнения буфера порта
                        for (int j = 0; j <= 10; j++)
                        {
                            if (port.BytesToRead == 1)
                            {
                                ReadData(1);//Прием ответа подтверждения
                                break;
                            }
                            else
                                Thread.Sleep(200);//Возможно потребуется коррекция задержки!!!
                            if (j == 10)          //******************************************
                            {
                                //Отключение прогрессбара
                                if (baroff != null)
                                    baroff();
                                return "Ошибка при записи!";
                            }
                        }
 
                        //Изменение адресов в запросе
                        writeblock[7] = (byte)((writeblock[7] + 0x10) & 0xff);
                        if (writeblock[7] == 0)
                            writeblock[8] += 1;
 
                        
                        //Уменьшение общ.размера на размер блока записи
                        datalength -= blocklen;
                        //Изменение индекса сдвига по массиву загр.данных
                        if (datalength < 0x20)
                        {
                            shiftindex += datalength;//Увеличение индекса сдвига
                            blocklen = datalength;   //Изменение размера блока записи
                        }
                        else
                        {
                            shiftindex += 0x20;//Увеличение индекса сдвига
                        }
                        //Событие прогресса при записи
                        if (barwrite != null)
                            barwrite();
 
                        //Обработка сообщений
                        Application.DoEvents();
                    }
                    while (datalength!=0);//Выход при нулевом размере загруженных данных
 
                    //Событие сброса прогресса
                    if (barclear != null)
                        barclear();
 
                    //**********Окончание записи в модуль**********
 
                    //Проверочное чтение
                    List<byte> dataread = new List<byte>();
                    if (!writecheck(ref dataread))
                    {
                        //Отключение прогрессбара
                        if (baroff != null)
                            baroff();
                        return "Ошибка при проверочном чтении!";
                    }
                        
 
                    //Проверочное сравнение
                    if (!datacompare(dataread, datawrite))
                    {
                        //Отключение прогрессбара
                        if (baroff != null)
                            baroff();
                        return "Ошибка сравнения данных!";
                    }
                        
 
                    //Включение WP
                    for (int wp = 0; wp < wpon.Length; wp++)
                    {
                        port.Write(wpon, wp, 1);
                    }
                    //Ожидание заполнения буфера порта
                    for (int j = 0; j <= 100; j++)
                    {
                        if (port.BytesToRead == 1)
                        {
                            ReadData(1);//Прием ответа подтверждения
                            break;
                        }
                        else
                            Thread.Sleep(100);
                        if (j == 100)
                        {
                            //Отключение прогрессбара
                            if (baroff != null)
                                baroff();
                            return "Устройство не отвечает!";
                        }
      
                    }
                }
                catch(Exception ex)
                {
                    //Отключение прогрессбара
                    if (baroff != null)
                        baroff();
                    return "Ошибка при записи"+"\n"+ ex.Message;
                }
            }
            //Отключение прогрессбара
            if (baroff != null)
                baroff();
            return "Запись прошла успешно";
        }
        //Метод сравнения записанных и считанных после записи данных
        private bool datacompare(List<byte> dataread, List<byte> datawrite)
        {
            int sizevector = (dataread[15] * 0x100 + dataread[14]) * 2;
            for (int i = 0; i < sizevector; i++)
            {
                if (dataread[i] != datawrite[i])
                    return false;
            }
            return true;
        }
        //Метод проверочного чтения
        bool writecheck(ref List<byte> readdata)
        {
            byte[] readblock = { 0xa5, 0xee, 0x02, 0x91, 0x30, 0x05, 0xa0, 0x00, 0x00, 0x07f, 0x00, 0x00 };
            List<byte>outdata=new List<byte>();
            List<byte>tempdata=new List<byte>();
 
            try
            {
                //Просчет КС блока
                readblock[11] = (byte)readblock.Sum(n => (int)n);
                //5 попыток соединения
                for (int i = 0; i < 5; i++)
                {
                    Thread.Sleep(200);
                    port.DiscardInBuffer();
                    port.Write(readblock, 0, readblock.Length);
 
                    //Ожидание заполнения буфера приема
                    int count = 0;
                    do
                    {
                        Thread.Sleep(100);
                        if (port.BytesToRead == 264)
                            break;
                        count++;
                    }
                    while (count != 5);
 
                    if ((i > 5) && (port.BytesToRead == 0))
                        return false;
                    else if (port.BytesToRead == 264)
                        break;
                }
 
                //Прием и фильтрация блока 
                tempdata.AddRange(ReadData(264));
                tempdata.RemoveRange(0, 7);
                tempdata.RemoveAt(tempdata.Count - 1);
 
                //Копирование в выходной массив
                readdata.AddRange(tempdata);
 
                //Основной блок чтения
                int counter = 0;
                for (int j = 0; j <= 0x1e; j++)
                {
                    //Сброс КС и очистка переменного массива
                    tempdata.Clear();
                    readblock[11] = 0;
 
                    //Коррекция адресов запроса
                    if (!((counter % 2) == 0))
                    {
                        readblock[7] = 0x00;
                        readblock[9] = 0x7f;
                        readblock[8] += 1;
                        readblock[10] += 1;
                    }
                    else
                    {
                        readblock[7] = 0x80;
                        readblock[9] = 0xff;
                    }
 
                    //Просчет КС запроса
                    readblock[11] = (byte)readblock.Sum(n => (int)n);
                    counter++;
 
                    //Запрос в порт
                    port.Write(readblock, 0, readblock.Length);
 
                    //Ожидание заполнения буфера приема
                    int count = 0;
                    do
                    {
                        Thread.Sleep(100);
                        if (port.BytesToRead == 264)
                            break;
                        count++;
                    }
                    while (count != 5);
 
                    if ((count == 5) || (port.BytesToRead == 0))
                        return false;
 
                    //Прием, фильтрация и копирование в выходной массив
                    tempdata.AddRange(ReadData(264));
                    tempdata.RemoveRange(0, 7);
                    tempdata.RemoveAt(tempdata.Count - 1);
                    readdata.AddRange(tempdata);
 
                    //Событие при проверочном чтении
                    if (barread != null)
                        barread();
 
                    //Обработка сообщений
                    Application.DoEvents();
                }
            }
            catch (Exception)
            {
                return false;
            }
            return true;
        }
 
        //Метод чтения блока  данных
        private List<byte> ReadData(int count)
        {
            List<byte> outData = new List<byte>();
            for (int i = 0; i < count; i++)
            {
                outData.Add((byte)port.ReadByte());
            }
            return outData;
        }
        //Функция переворота байтов (конвертирование bin>>eep>>bin)
        public List<byte> EepToBin(List<byte> Data)
        {
            List<byte> outLIst = new List<byte>();
            for (int i = 0; i <= Data.Count - 1; i++)
            {
                if (((i + 1) % 2) == 0)
                {
                    outLIst.Add(Data[i - 1]);
                }
                else
                {
                    if (i == Data.Count - 1)
                    {
                        outLIst.Add(Data[i]);
                        break;
                    }
                    outLIst.Add(Data[i + 1]);
                }
            }
            return outLIst;
        }
    }
}

0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
09.02.2014, 13:49
Цитата Сообщение от insite2012 Посмотреть сообщение
Это только его часть.
Честно говоря, километровый размер метода не делает честь, а как раз-таки наоборот...
0
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
09.02.2014, 13:54
Цитата Сообщение от Psilon Посмотреть сообщение
Честно говоря, километровый размер метода не делает честь, а как раз-таки наоборот...
Так я его и так постарался разбить на несколько смысловых кусков... Запись, чтение, проверка, отдельно маленький метод считывания...
Ну а все-таки, такой возврат результата функции - корректен или нет?
Я сначала хотел возвращать int, по ситуации (0, 1, ..., читал про С++, и что-то в голове отложилось про проверку кода возврата функции ), но потом подумал, мне так или иначе проверять код возврата, так пусть сразу строка и возвращается...
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
09.02.2014, 14:49
insite2012, почитайте про флаги возврата вс исключения...
https://www.cyberforum.ru/post... l?langid=3
0
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
09.02.2014, 15:15
Так в том и дело, что в данной ситуации исключение, как правило, будет всегда одно - по таймауту чтения из порта... Других там в принципе не будет. И как локализовать, где именно прошло исключение? А таким образом я точно знаю, что пошло не так в программе... Хотя, естественно, мой метод не идеален вообще, но мне он в данной ситуации подошел больше всего...
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
09.02.2014, 15:24
insite2012, когда бросается исключение, во-первых можно бросать разного типа исключения, во-вторых он пишет, на какой строке он выпал, в-третьих можно кастомное сообщение писать. Нет таких кодов ошибки, которые нельзя было бы переделать в исключения без ухудшения кода...
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
09.02.2014, 15:24
Помогаю со студенческими работами здесь

Передать массив значений в другой класс
Есть у меня программа Лабиринт. генерирует рандомный лабиринт. Каждая клетка имеет 4 стены со значением 0 или 1 Также я создал...

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

Как передать переменные в другой класс?
Всем привет. Не могу передать переменную в другой класс. Буду благодарна, если вы мне объясните в чем проблема. Вот у меня есть класс...

Как передать ссылку по клику в другой класс?
как передать ссылку по клику в другой класс есть класс парсера вот часть кода protected InputStream getInputStream() { ...

Как правильно передать ссылку в другой класс
Добрый день! Есть класс class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { @IBOutlet...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Переходник USB-CAN-GPIO
Eddy_Em 20.03.2026
Достаточно давно на работе возникла необходимость в переходнике CAN-USB с гальваноразвязкой, оный и был разработан. Однако, все меня терзала совесть, что аж 48-ногий МК используется так тупо: просто. . .
Оттенки серого
Argus19 18.03.2026
Оттенки серого Нашёл в интернете 3 прекрасных модуля: Модуль класса открытия диалога открытия/ сохранения файла на Win32 API; Модуль класса быстрого перекодирования цветного изображения в оттенки. . .
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru