#c# #polymorphism
#c# #полиморфизм
Вопрос:
Я не знаю, как это правильно объяснить, кто-нибудь, пожалуйста, отредактируйте мой заголовок и публикацию по мере необходимости. Я думал, что это можно решить с помощью полиморфизма, но я не смог заставить его работать. То, что я хотел бы иметь, заключается в следующем.
У меня будут разные формы, и все они будут иметь разные переменные. Например, для описания конкретной формы A мне нужно:
Обязательные поля для каждой формы:
-
начальная и конечная точки (состоят из 3 двойных переменных: x, y и z)
-
имя (строка)
Фигуре могут потребоваться или не потребоваться следующие поля (возможно, в будущем мне понадобится больше)
- Длина, ширина, высота (все двойные)
- Угол
- Другие переменные, которые могут быть double или string
Дело в том, что это должно быть гибким, поскольку каждая форма будет описываться с использованием XML, который мне затем нужно загрузить в программу. Например, куб будет работать следующим образом:
<?xml version="1.0" encoding="utf-8" ?>
<structure name="Cube">
<variables>
<point name="start" />
<point name="end" />
<length name="width" min="1" max="10000" unit="mm" />
<length name="height" min="1" max="10000" unit="mm" />
</variables>
<points>
<point name="topLeft">
<x>start.x</x>
<y>start.y - height/2</y>
<z>start.z</z>
</point>
<point name="topRight">
<x>end.x</x>
<y>end.y - height/2</y>
<z>end.z</z>
</point>
<point name="bottomLeft">
<x>start.x</x>
<y>start.y height/2</y>
<z>start.z</z>
</point>
<point name="bottomRight">
<x>end.x</x>
<y>end.y height/2</y>
<z>end.z</z>
</point>
</points>
<connections>
<connection type="line">
<point name="topLeft" />
<point name="topRight" />
<point name="bottomRight" />
<point name="bottomLeft" />
<point name="topLeft" />
</connection>
</connections>
</structure>
Итак, я подумал, что у меня есть базовый класс под названием CVariable (с двумя абстрактными методами, parseString и toString), который я затем наследую, чтобы сделать CLength (новый атрибут двойной длины), CPoint (новый атрибут двойной длины x, y и z) и CName (новое строковое имя атрибута). Тогда у меня может быть класс с именем CShape, который содержит список переменных, CPoint и CName (соединения, просто имя, идентифицирующее точку, к которой нужно подключиться). Я полагаю, проблема в том, что если у меня есть список переменных, я не могу получить доступ к новым атрибутам. Я прав?
Извините, если это непонятно, я отредактирую, чтобы добавить любую необходимую информацию. Заранее большое спасибо.
Комментарии:
1. Краткое замечание, но оно будет сильно раздражать многих людей: не начинайте имена классов с
C
префикса. Это соглашение от MFC, в значительной степени.. не сделано в . СЕТЕВОЙ мир.
Ответ №1:
Схема, о которой вы думаете, обычно называется «вариантом». CVariable
это неподходящее название для этого, оно просто не конкретизирует. Но вы уже думаете в правильном направлении. Производя из общего базового класса, вы можете упаковать элементы в общий контейнер. Хитрость для доступа к этим производным типам заключается в использовании информационной системы о типах среды выполнения: есть typeof
ключевое слово, сообщающее вам фактический тип объекта, на который вы ссылаетесь: http://msdn.microsoft.com/de-de/library/58918ffs.aspx
Небольшое предупреждение: Попадание в ситуацию, когда требуется вариант, часто является намеком на то, что что-то в дизайне структуры данных может быть ошибочным, и переосмысление проблемы — хорошая идея.
Комментарии:
1. Привет, datenwolf, спасибо за советы. Я создал CVariable как абстрактный класс, и я только что прочитал о ковариации. Разве не должно быть возможно иметь список переменных? Таким образом, я могу затем получить производный класс, используя typeof. Но я получаю следующую ошибку: не удается создать экземпляр абстрактного класса. Что на самом деле имеет смысл, но затем я снова застрял.
2. Правильно, абстрактные классы не могут быть созданы. Вам нужно вывести из вашего базового класса variant классы в соответствующие классы (Line, Point и т.д.), Создать их экземпляр, а затем добавить их к списку вариантных ссылок . Это не будет работать с самим списком вариантов, только со ссылками. В MSDN есть отличный пример полиморфизма, который, кстати, действительно делает то, что вы задумали: msdn.microsoft.com/en-us/library/ms173152.aspx#Y319
Ответ №2:
Из того, что я вижу, вы перегибаете палку. Почему бы просто:
<cube center-x="44" center-y="-43" center-z="20" edge-length="42" />
<sphere center-x="0" center-y="1" radius="3" />
Затем каждый класс будет отвечать за загрузку самого себя из представления XML и сериализацию самого себя обратно в XML.
Однако, если вам нужно иметь возможность описать произвольный 3D-объект, вам необходимо описать отдельные грани и вершины.
Возможно, я сильно ошибаюсь, но опять же: я не знаю всех требований.
Комментарии:
1. Дело в том, Антон, что все формы являются 3D, но они описываются как 2D (что делает это немного проще), а затем выдавливаются. Но у нас могут быть произвольные причудливые формы. Вот почему мне нужно, чтобы это было как можно более гибким. Хотя спасибо за идею.