Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > VB .NET > как создать элемент структуры с массивом


Автор: kobalt 24.9.2008, 14:31
есть структура  poi основанная на структуре   point

при создание элемента el1 структуры poi 
выдается ошибка:
Дополнительные сведения: В экземпляре объекта не задана ссылка на объект.

как правильно создать элемент el1 ?

Код

Public Structure poi
        Public i As Double
        Public pp() As point
    End Structure

    Public Structure point
        Public x As Double
        Public y As Double
    End Structure

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim el1 As poi
        el1.i = 5
        el1.pp(1).x = 3
    End Sub




Автор: Pilger 24.9.2008, 17:36
Объект создается так:
Код

Dim el1 As New Poi


или так:
Код

Dim el1 As Poi
el1 = New Poi


Автор: diadiavova 24.9.2008, 17:43
Думаю, в данном случае ошибка возникает в строке
Код

el1.pp(1).x = 3

Дело в том, что в самой структуре, ты объявляешь пустой массив, а потом обращаешься к индексу 1 этого массива. Тебе нужно либо переопределить массив перед использованием, либо вообще вместо массива использовать коллекцию(по-моему оптимальный вариант).

Автор: kobalt 24.9.2008, 18:50
Pilger,  пробовал ваш вариант - не работает

Автор: diadiavova 24.9.2008, 20:58
Цитата

пробовал ваш вариант - не работает 

Ну дык, ясный перец не будет работать. Для разнообразия можно было бы и на моё замечание обратить внимание. Я же объяснил, что NullReferenceException вызывает не структура, а её поле pp. Оно пустое, естественно обращаться к нему нельзя. А вариант, предложенный Pligerом, от твоего ни чем не отличается. Ну если ты считаешь, что diadiavova просто гонит, тогда - удачи.

Автор: kobalt 25.9.2008, 15:36
сейчас читаю про коллекции (раньше  с ними не работал).

В самой структуре объявить непустой массив не удается. 
Как переопределить массив перед использованием?

Автор: Pilger 25.9.2008, 17:30
Цитата(kobalt @ 24.9.2008,  18:50)
Pilger,  пробовал ваш вариант - не работает

Знаю. Извиняюсь, не правильно понял проблему.
Diadiavova предложил такой вариант:
"Тебе нужно либо переопределить массив перед использованием"
Тобишь это будет так:
Код

        Dim el1 As poi
        el1.i = 5
        ReDim el1.pp(5)
        el1.pp(1).x = 3

Автор: diadiavova 25.9.2008, 19:32
В общем и целом Pilger ответил на вопрос, однако, судя по всему, здесь потребуются некоторые дополнительные разъяснения. 
Если говорить о массивах то они создаются при объявлении в том случае, когда указаны индексы, в ином случае, объявляется просто пустая переменная(как и произошло), тогда можно переопределить, используя конструкцию ReDim(как предложил Pilger) или просто присвоить полю значение. Например так
Код

Dim pa(3) As point
el1.pp = pa

Разницы нет.
При этом надо иметь в виду, что если конструкция ReDim используется для увеличения количества индексов её следет применять со словом Preserve.
Если нужно, чтобы массив создавался внутри структуры, здесь всё зависит от задач, стоящих перед тобой. Например: если известно заранее сколько будет элементов в массиве, и это число фиксированное - то нет проблем, приведу пример для случая, когда в массиве 5 элементов
Код

    Public Structure poi
        Public i As Double
        Public pp(4) As point
    End Structure

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

    Public Structure poi
        Public Sub New(ByVal poinCount As Integer, ByVal ind As Double)
             ReDim pp(poinCoun - 1)
             i = ind
        End Sub
        Public i As Double
        Public pp() As point
    End Structure


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

Dim el1 As New poi(10, 5)

в результате получится объект с десятью элементами в массиве, а поле i будет равно 5.

Что касается структуры point. Во-первых, в пространстве System.Drawing имеется две похожие структуры (Point и PointF), прежде, чем создавать свою, рассмотри возможность использования одной из них. Если же ни одна не подойдёт, всё равно называть свою структуру point - плохая идея, пространство это импортируется в проект по умолчанию, а дублирование имён может привести к конфликту(сам запутаешься).

Автор: kobalt 26.9.2008, 09:34
Спасибо, все работает! smile  smile  smile 

PS: структуру point взял где то из примеров - использую для описания координат точек на плоскости 

PPS: сейчас описываю задачу формулами, после понадобится рисование несложной графики на плоскости (передвигающиеся линии, окружности) - не могли бы взяться (разумеется не бесссплатно)

Автор: diadiavova 26.9.2008, 11:25
Если точки нужны для рисования графики - тем более лучше использовать "родные" (из System.Drawing). Например: прорисовка многоугольника требует передачи массива точек, естественно "родных" конвертирование требует дополнительных затрат. Насчёт взяться - надо посмотреть, что там за задача.

Автор: diadiavova 27.9.2008, 00:55
Кстати, в сообщении, где я привёл следующий код:
Код

    Public Structure poi
        Public i As Double
        Public pp(4) As point
    End Structure


я слегка ошибся. В структурах инициировать массив нельзя. То есть можно использовать либо второй вариант(где массив инициируется в конструкторе), либо переопределять его вне кода самой структуры.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)