2015-10-23 2 views
1

У меня есть доступ к абстрактному методу, который принимает тип под названием «Оружие».передать объект и преобразовать его на лету

Объект, который я передаю, имеет ссылку на родителя, но мне нужно сделать преобразование.

Выполнение одного действия, похоже, работает нормально, но для других методов мне может понадобиться передать 3, 4 или даже 5 объектов, что означает, что мне придется преобразовать все из них, прежде чем я смогу получить доступ свойства, которые мне нужны.

Есть ли способ передать в преобразовании вместо фактического объекта, который содержит ссылку?

Что-то вроде этого, и я знаю, что это не компилируется:

GetRobotSystems(Weapon r=(MilitaryRobot)r.Baserobot) 

Вот рабочий код:

protected override IEnumerable<WeaponsCollection> GetRobotSystems(Weapon robot) 
{ 
    MilitaryRobot r = (MilitaryRobot)robot.BaseRobot; 

    yield return r.Aromor; 
    yield return r.Weapons; 

} 
+5

Я не понимаю, чего вы пытаетесь достичь. Если метод ожидает «MilitaryRobot», почему бы не изменить объявление метода соответственно? – Amy

+1

Я чувствую, что основная причина проблемы заключается в вашем дизайне и дать вам какую-то конкретную помощь, вам нужно будет опубликовать хотя бы часть вашей иерархии классов. –

ответ

1

Интерфейсный подход, который описывает Эрик, является прекрасным решением этой проблемы с игровым объектом, но композиция также может работать.

Проблема заключается в том, что вы смешиваете композиции и образцы наследования здесь, которые в конечном итоге будут немного беспорядочны.

Идея иметь «игровой объект» более высокого уровня с свойствами «Оружие/Броня» в порядке. Это образец композиции.

Но почему же у вас есть шаблон наследования Robot/MilitaryRobot? Вы можете отбросить функции, которые отличают разницу между этими разными типами и изменить их на свойства более общего «Актера» или «GameObject».

Композиционные узоры, подобные этой, отлично работают в игровом дизайне. Но схемы наследования, вероятно, приведут к хрупкому и почти невозможному рефакторингу.

4

У меня есть доступ к абстрактному методу, который принимает тип называется «Оружие».

Нет, у вас нет абстрактного метода. Он знает только, как обращаться с объектами типа MilitaryRobot.

Если у всех Weapon.BaseRobot есть свойства Armor and Weapons, тогда нет необходимости бросать в MilitaryRobot. Если не все Weapon.BaseRobot имеют эти свойства, вы можете также изменить подпись метода, чтобы принять один конкретный тип, который метод знает, как обращаться.

Обратите внимание, что при написании этого типа кода интерфейсы чрезвычайно полезны. Например, вы можете определить IWeaponized и иметь все, что имеет оружие, реализующее этот интерфейс, в то время как все, что бронировано, может реализовать интерфейс IArmored. Что-то, что является оружием и бронированным, будет реализовывать оба этих интерфейса. Ваши общие методы будут принимать интерфейсы, а не классы.