Я пытаюсь использовать полиморфизм, чтобы производный класс работал с производным свойством вместо базового свойства. Я не уверен, как выразить это более понятными словами, поэтому вот пример с выводом:
// setup output to demonstrate the scenario
static void Main(string[] args)
{
var foo = new Foo();
var foobase = foo as FooBase;
Console.WriteLine("Foo is null? {0}", foo == null);
Console.WriteLine("Foo.Bar is null? {0}", foo.Bar == null);
Console.WriteLine("FooBase is null? {0}", foobase == null);
Console.WriteLine("FooBase.Bar is null? {0}", foobase.Bar == null);
Console.ReadLine();
}
// base and derived. These represent my problem.
class BarBase { }
class Bar : BarBase { }
// Base implementation using base properties
class FooBase
{
public virtual BarBase Bar { get; set; }
public FooBase() { }
}
// Derived implementation using "new" to operate with the
// derived the property
class Foo : FooBase
{
public new Bar Bar { get; set; }
public Foo() : base()
{
// populate our modified property with the derived class
Bar = new Bar();
//base.Bar = Bar; // I don't want to do this, but how can I avoid it?
}
}
ВЫВОД:
Foo is null? False
Foo.Bar is null? False
FooBase is null? False
FooBase.Bar is null? True
Проблема в том, что «FooBase.Bar» имеет значение NULL. Я понимаю, что модификатор new скрывает базовую реализацию, поэтому я знаю, что могу заставить ее работать, добавив (закомментированную) строку:
base.Bar = Bar; // I don't want to do this, but how can I avoid it?
Есть ли лучший способ? Чего мне не хватает?
Заранее спасибо!
РЕДАКТИРОВАТЬ (6/7/11)
Добавление более конкретного примера к моей проблеме. В основном, есть абстрактные реализации для Игры и Камеры (очень основные здесь ...). Абстрактная игра использует абстрактную камеру для основной работы. Производная игра использует свою производную камеру для своей специальной работы. В конце концов, мне нужно, чтобы как производные, так и абстрактные камеры работали в своей собственной области.
Я дал две разные реализации Camera и две реализации Game, чтобы (надеюсь) продемонстрировать гибкость, которую я ищу. Обратите внимание, что Game1 использует «взлом», чтобы заставить базовую камеру иметь значение - Game2 не делает этого. Game1 имеет поведение Я хочу, но не реализация Я хочу.
class GameAndCameraExample
{
static void Main(string[] args)
{
new Game1().Play();
Console.WriteLine();
new Game2().Play();
Console.ReadLine();
}
// abstract camera
abstract class CameraBase
{
public void SpecialCameraBaseMethod()
{
Console.WriteLine("SpecialCameraBaseMethod");
}
}
// camera implementation
class ChaseCamera : CameraBase
{
public void SpecialChaseCameraMethod()
{
Console.WriteLine("SpecialChaseCameraMethod");
}
}
// a different camera implementation
class FlightCamera : CameraBase
{
public void SpecialFlightCameraMethod()
{
Console.WriteLine("SpecialFlightCameraMethod");
}
}
// abstract game
abstract class GameBase
{
public virtual CameraBase Camera { get; set; }
public GameBase() { }
public virtual void Play()
{
Console.WriteLine("GameBase.Camera is null? {0}", Camera == null);
if(Camera != null) // it will be null for Game2 :-(
Camera.SpecialCameraBaseMethod();
}
}
// awesome game using chase cameras
class Game1 : GameBase
{
public new ChaseCamera Camera { get; set; }
public Game1() : base()
{
Camera = new ChaseCamera();
base.Camera = Camera; // HACK: How can I avoid this?
}
public override void Play()
{
Console.WriteLine("Game.Camera is null? {0}", Camera == null);
Camera.SpecialChaseCameraMethod();
base.Play();
}
}
// even more awesome game using flight cameras
class Game2 : GameBase
{
public new FlightCamera Camera { get; set; }
public Game2()
: base()
{
Camera = new FlightCamera();
}
public override void Play()
{
Console.WriteLine("Game.Camera is null? {0}", Camera == null);
Camera.SpecialFlightCameraMethod();
base.Play();
}
}
}
ВЫВОД:
Game.Camera is null? False
SpecialChaseCameraMethod
GameBase.Camera is null? False
SpecialCameraBaseMethod
Game.Camera is null? False
SpecialFlightCameraMethod
GameBase.Camera is null? True
Является ли наследование даже лучшим подходом для этого?