Как смоделировать неизвестное количество переменных с помощью C#

#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 (что делает это немного проще), а затем выдавливаются. Но у нас могут быть произвольные причудливые формы. Вот почему мне нужно, чтобы это было как можно более гибким. Хотя спасибо за идею.