Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.69/13: Рейтинг темы: голосов - 13, средняя оценка - 4.69
0 / 0 / 0
Регистрация: 06.10.2017
Сообщений: 11
1

Как использовать массив созданного класса?

06.10.2017, 10:21. Показов 2331. Ответов 33
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Пытаюсь создать массив нового класса переменных и не получается, выдаёт ошибку. Помогите исправить:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
class MyP
{
       public double X, Y;
}
 
private MyP[] Ps = new MyP[100];
 
private void MyCalc()
{
      int j=1;
      Ps[j].X = 1;
      //Ps.ElementAt(j).X = 1;
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
06.10.2017, 10:21
Ответы с готовыми решениями:

Обращение к переменной созданного класса
Понимаю, что все уже изъезжено по 100 раз, но в упор не могу понять следующую вещь! У меня есть...

Уникальный идентификатор созданного объекта класса
Задание. Составить описание класса для объектов-векторов, задаваемых одномерным массивом...

Проблема с присвоением объектов созданного класса
Задание было таким: решение задачи на оптимизацию симплекс методом. Рекомендовалось считать в...

Демонстрация возможностей созданного класса в методе Main()
Здравствуйте уважаемые программисты) Мне нужна ваша помощь. Большую часть я уже сделала, осталось...

33
910 / 795 / 329
Регистрация: 08.02.2014
Сообщений: 2,391
06.10.2017, 10:23 2
что за ошибка, в каком месте ошибка, тут экстрасенсов нету
0
0 / 0 / 0
Регистрация: 06.10.2017
Сообщений: 11
06.10.2017, 10:26  [ТС] 3
Во время работы программы, на строке 11 , кода пытаюсь использовать переменную Ps[j].X = 1 выдаёт ошибку :
System.NullReferenceException: "Ссылка на объект не указывает на экземпляр объекта."
0
911 / 815 / 333
Регистрация: 03.02.2015
Сообщений: 5,265
Записей в блоге: 9
06.10.2017, 10:45 4
Вам создавать обьекты массива нужно, а за тем уже к ним обращаться. MyP - это же класс, а значит new нужно писать.

C#
1
2
3
4
5
6
7
private void MyCalc()
{
      int j=1;
      Ps[j] = new MyP();
      Ps[j].X = 1;
 
}
Добавлено через 5 минут
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class MyP
{
       public double X {set; get} = 0;
       public double Y {set; get} = 0;
}
 
private int const Len = 100;
private MyP[] Ps;
 
void Init()
{
  Ps = new MyP[Len];
  for (int i =0; i < Len; i++)
  {
     Ps [i] = new MyP();
  }
}
Вызовете Init, что бы инициализировать Вас массив, а дальше работайте с ним.
1
0 / 0 / 0
Регистрация: 06.10.2017
Сообщений: 11
06.10.2017, 12:17  [ТС] 5
Спасибо, с Вашей помощью начало получаться, почти Delphi.
Пишу примерно так:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
       class MyP
        {
          public double X, Y;
        }
        private MyP[] Ps = new MyP[0];
 
        private void MyCalc()
        {
            for (int j =0; j < 100; j++)
            {
                MySetLength(ref Ps, j);
                Ps[j].X = 1;
                Ps[j].Y = 2;
            }
       }
 
        private void MySetLength(ref MyP[] AnyPs,int i)
        {
           Array.Resize(ref AnyPs, i + 1);
           AnyPs[i] = new MyP();
        }
Единственно хотелось бы, чтобы не писать MySetLength для каждого созданного класса, объявить в ней не MyP[], а какой-нибудь общий массив array. Не знаю как это сделать?
0
911 / 815 / 333
Регистрация: 03.02.2015
Сообщений: 5,265
Записей в блоге: 9
06.10.2017, 12:45 6
SidNiko,

Метод Init инициализируйте сразу элементы.
Или можете использовать список List, можно добавлять и удалять элементы очень просто.

примерно так:

C#
1
2
3
4
List<MyP> ListMyP = new List<MyP>();
 
// Добавляем новый элемент
ListMyP.Add(new MyP());
У Вас цель какая?
0
910 / 795 / 329
Регистрация: 08.02.2014
Сообщений: 2,391
06.10.2017, 12:59 7
Лучший ответ Сообщение было отмечено SidNiko как решение

Решение

Размерность массива задавай сразу, используй Array.Resize только когда уже заполнился тот что ты создал и уж очень нужно расширить.
Метод:
C#
1
2
3
4
private void MySetLength<T>(ref T[] AnyPs, int i) where T:class, new()
        {
            AnyPs[i] = new T();
        }
Добавлено через 3 минуты
Лучше даже вот так:
C#
1
2
3
4
5
6
7
void InitArray<T>(ref T[] AnyPs) where T:class, new()
        {
            for (var i = 0; i < AnyPs.Length; i++)
            {
                AnyPs[i] = new T();
            }
        }
1
0 / 0 / 0
Регистрация: 06.10.2017
Сообщений: 11
06.10.2017, 12:59  [ТС] 8
Спасибо, всё круто, заработало, так и добавил:

C#
1
2
3
4
5
        private void MySetLength<T>(ref T[] AnyPs, int i) where T : class, new()
        {
            Array.Resize(ref AnyPs, i + 1);
            AnyPs[i] = new T();
        }
0
910 / 795 / 329
Регистрация: 08.02.2014
Сообщений: 2,391
06.10.2017, 13:25 9
SidNiko, только никому это не показывай) ты при каждой новой инициализации будешь создавать новый объект массива из-за Array.Resize, производительность твоя упадёт в нули от такого поведения.
0
0 / 0 / 0
Регистрация: 06.10.2017
Сообщений: 11
06.10.2017, 15:30  [ТС] 10
SeIZVeIZ, это понятно, но просто бывает такое - когда ещё не известна длина массива, и там выше в цикле на самом деле не for, а while, и когда таких точек не очень много, и сделать это нужно один раз, например, при открытии файла, то не страшно, что немного упадёт производительность, этого никто не заметит, а деваться некуда.

Добавлено через 1 час 55 минут
SeIZVeIZ, и это ведь вообще проблема C#, что при создании массива нужно инициализировать каждый объект в нём (читал раньше эту проблему хотят доработать в версии 7), в этом и был изначально весь вопрос данной темы, нерешённый в других постах. На Delphi, сразу весь массив какого-то типа переменных при изменении его длины приобретает начальные значения этого типа, а на C#, который является как и все языки C, очередной итерацией в попытке достичь уровня Delphi, приходится как ты в первом сообщении написал "создавать объекты массива". Хотя и в Delphi в данной задаче лучше бы один раз назначить длину массива, чем каждый раз менять, но по-моему там это вообще без разницы по скорости выполнения, там это как то динамически происходит, прост добавляется ссылка
0
910 / 795 / 329
Регистрация: 08.02.2014
Сообщений: 2,391
06.10.2017, 16:02 11
SidNiko, массив класса по умолчанию и есть null, массивы чисел например будут нулями. А 7 версия шарпа вышла уже

Добавлено через 9 минут
Могу предложить вот такой вариант:
Enumerable.Repeat(new Element(), 100).ToArray();
инициализирует массив класса Element на 100 значений
0
0 / 0 / 0
Регистрация: 06.10.2017
Сообщений: 11
06.10.2017, 16:05  [ТС] 12
SeIZVeIZ,
вот и приходится писать
C#
1
private MyP[] Ps = new MyP[0];
а не
C#
1
private MyP[] Ps;
потому что спросив у такой переменной Length, и ожидая ноль - получаешь ошибку.
И пробовал вставлять при создании класса как обещали в версии 7 всякие знаки !, чтобы по умолчанию объекты имели нулевые значения, а получал ошибки.
0
1150 / 742 / 483
Регистрация: 21.01.2014
Сообщений: 1,903
06.10.2017, 16:24 13
SidNiko, а какое начальное значение у типа, например, у которого есть один конструктор, который принимает интерфейс? ИМХО, большинство проблем такого рода возникают из за того, что человек начиная писать на новом языке делает это так, как будто он пишет на старом.
0
Администратор
Эксперт .NET
17019 / 13372 / 5217
Регистрация: 17.03.2014
Сообщений: 27,342
Записей в блоге: 1
06.10.2017, 16:36 14
Цитата Сообщение от SidNiko Посмотреть сообщение
И пробовал вставлять при создании класса как обещали в версии 7 всякие знаки !, чтобы по умолчанию объекты имели нулевые значения, а получал ошибки.
Это называется "слышал звон, да не знаю где он".
0
Эксперт .NET
12079 / 8388 / 1281
Регистрация: 21.01.2016
Сообщений: 31,601
06.10.2017, 16:58 15
Цитата Сообщение от SidNiko Посмотреть сообщение
и это ведь вообще проблема C#, что при создании массива нужно инициализировать каждый объект в нём (читал раньше эту проблему хотят доработать в версии 7), в этом и был изначально весь вопрос данной темы, нерешённый в других постах.
Это не проблема C#, а чисто ваша. Проходит по мере изучения языка.
0
Каждому свое
533 / 219 / 81
Регистрация: 05.08.2013
Сообщений: 1,614
06.10.2017, 18:12 16
SidNiko,
Цитата Сообщение от SidNiko Посмотреть сообщение
и это ведь вообще проблема C#, что при создании массива нужно инициализировать каждый объект в нём
Дело в том, что в если Вы храните в массиве на C# объекты ссылочного типа, то соответственно их нужно создавать перед добавлением и хранением в этом массиве. Подобно в C++ в контейнерах можно хранить указатели, и прежде чем их там хранить, нужно создать объекты на которые они указывают. Другое дело, в C++, при объявлении статического массива, можно не создавать объекты, чтобы потом добавить их, так как в массиве хранятся не ссылки, а сразу же объекты. Все на стеке
0
0 / 0 / 0
Регистрация: 06.10.2017
Сообщений: 11
06.10.2017, 18:24  [ТС] 17
Если уж у нас пошла такая беседа, когда все проблемы благодаря вами успешно решены, поговорим:
OwenGlendower,
Т.е. версия 7 не оправдала ожидания, всё по-старому, всё-также поштучно создаём объекты массива?
Usaga,
Просто есть вы крутые только программисты, а например инженерам все эти выкрутасы - не надо, поэтому большинство написанных профессиональных инженерных программ написано на Delphi, потому что им все эти телеги которые мы тут приписали и все костыли как вы говорите - не нужны. Хочется программу быстро и просто писать, задумываясь только об её алгоритме
0
Администратор
Эксперт .NET
17019 / 13372 / 5217
Регистрация: 17.03.2014
Сообщений: 27,342
Записей в блоге: 1
06.10.2017, 18:54 18
Цитата Сообщение от SidNiko Посмотреть сообщение
Т.е. версия 7 не оправдала ожидания, всё по-старому, всё-также поштучно создаём объекты массива?
Чьи ожидания? Мои - оправдала. Ваши, основанные на непонятной информации видимо нет. Обещаний что создание массива в C# 7 будет означать создание элементов я не помню.

Цитата Сообщение от SidNiko Посмотреть сообщение
большинство написанных профессиональных инженерных программ написано на Delphi
Что такое "инженерная программа" и на основании чего ты считаешь что большинство таких программ пишется именно на Delphi?
0
Эксперт .NET
12079 / 8388 / 1281
Регистрация: 21.01.2016
Сообщений: 31,601
06.10.2017, 19:13 19
Цитата Сообщение от SidNiko Посмотреть сообщение
Хочется программу быстро и просто писать, задумываясь только об её алгоритме
Для этого просто нужно быть специалистом. А если не получается, то язык в этом виноват в последнуюю очередь.

Добавлено через 16 минут
Цитата Сообщение от SidNiko Посмотреть сообщение
Просто есть вы крутые только программисты, а например инженерам все эти выкрутасы - не надо,
Ещё хотелось бы понять, как "инженеры" видят поведение компилятора заполняющего за них массив абстракций (абстрактных классов или интерфейсов) или классов без конструктора по умолчанию. Т.е. вещами, для создания которых у компилятора просто нет нужной информации. Или как они обоснуют такое поведение, если мне нужен именно пустой массив, в который я буду копировать уже существующие объекты? Т.е. на кой чёрт программа будет расходовать время и ресурсы на заполнение массива данными, которые я тут же перезапишу совсем другими? А что если я собираюсь работать с дочерними классами, а не с теми, что в объявлении массива указаны?

Я к тому, что многие "неудобства" инструмента вытекают из полного непонимания и никакущей компетенции недовольного, а не из-за недостатков самого инструмента.
0
0 / 0 / 0
Регистрация: 06.10.2017
Сообщений: 11
07.10.2017, 13:01  [ТС] 20
Цитата Сообщение от OwenGlendower Посмотреть сообщение
Что такое "инженерная программа"
OwenGlendower, есть такие: совсем инженерная старая Slope; ближе к научно-исследовательским - Plaxis; такая интересная программа как SAS Planet.
Был в одной, как считается, из самых развитых стран, а там ребята на-полном серьёзе докладывались на брифинге как неделями скринят google/map, для них было откровением увидеть как со свободным нашим российским SAS Planet, любые картографические источники склеивются за минуту с нужным зумом, и при том уже с привязкой проекций.
И сам написал программы, которые работают просто невероятно, в них массивы из миллионов уравнений последовательно (по времени) в матрицах параллельно потоками решаются миллионы раз, с такой скоростью, что считалось это не возможно, и что нужно их разряжать треугольными сетками, и всё это благодаря эффективному языку.
Цитата Сообщение от Usaga Посмотреть сообщение
по мере изучения языка
Usaga, эти догмы, звучащие как мантра - " Надо изучать язык", сомнительны, может быть всё-таки лучше быстро решить задачу, так как она была написана в первом посте этой темы, без всех телег которые последовали?
0
07.10.2017, 13:01
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
07.10.2017, 13:01
Помогаю со студенческими работами здесь

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

Как в Form использовать процедуры пользовательского класса
Здравствуйте уважаемые программисты. Мне задали задачку, которую саму по себе я предстовляю и...

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

Как правильно использовать нестатические методы класса
здраствуйте. у меня можно так сказать этический вопрос, по поводу использования нестатических...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru