I'm trying to use Polymorphism to have a derived class operate with a derived property instead of the base property. I'm not sure how to put it in clearer words, so here's an example with the output:
// 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?
}
}
OUTPUT:
Foo is null? False
Foo.Bar is null? False
FooBase is null? False
FooBase.Bar is null? True
The problem is "FooBase.Bar" is NULL. I understand that the new modifier is hiding the base implementation, that's why I know I can make it work by adding the (commented out) line:
base.Bar = Bar; // I don't want to do this, but how can I avoid it?
Is there a better way? What am I missing?
Thanks in advance!
EDIT (6/7/11)
Adding a more specific example to my problem. Basically, there are abstract implementations for a Game and a Camera (very basic here...). The abstract Game uses the abstract Camera for basic work. The derived Game uses its derived Camera for its specialty work. In the end, I'd need both the derived and the abstract Cameras to work in their own scope.
I've given two different Camera implementations and two Game implementations to (hopefully) demonstrate the flexibility I'm looking for. Please note that Game1 uses a "hack" to force the base Camera to have a value- Game2 does not do this. Game1 has the behavior I want, but not the implementation I want.
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();
}
}
}
OUTPUT:
Game.Camera is null? False
SpecialChaseCameraMethod
GameBase.Camera is null? False
SpecialCameraBaseMethod
Game.Camera is null? False
SpecialFlightCameraMethod
GameBase.Camera is null? True
Is inheritance even the best approach for this?
You need to use override instead of new.
You can still return a Bar object, thought it will still return as BarBase. But override is the only way to make sure that Foo's property is used instead of FooBase's property when the Foo object is cast as FooBase.
Generics could help in this situation, mainly on the FooBase class:
class FooBase<T> where T: BarBase {
public virtual T Bar { get; set; }
public FooBase() { }
}
class Foo : FooBase<Bar> {
public override Bar Bar { get; set; }
public Foo() : base() {
Bar = new Bar();
}
}
And here's the modifications to Main():
static void Main( string[] args ) {
var foo = new Foo();
var foobase = foo as FooBase<Bar>;
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.ReadKey();
}
The constraint of generic parameter T to BarBase means any subclass of FooBase can opt-in to any subclass of BarBase, or just deal with BarBase:
class VagueFoo : FooBase<BarBase> { }
I'm going to present an answer to my own question. Actually, two answers. There are likely many other answers but none are finding their way here.
Solution #1: Parallel Hierarchies
This idea was brought up by #Joel B Fant in an earlier comment. I looked over how ADO.NET is implemented (via Reflector) to come up with an implementation. I'm not thrilled about this pattern because it means multiple properties for the same family of objects- but it is a reasonable solution.
(Let's assume that the CameraBase, FlightCamera, and ChaseCamera from my question are still defined to save space)
CODE
// abstract game
abstract class GameBase
{
public virtual CameraBase CameraBase { get; set; }
public GameBase() { }
public virtual void Play()
{
Console.WriteLine("GameBase.CameraBase is null? {0}", CameraBase == null);
if (CameraBase != null)
CameraBase.SpecialCameraBaseMethod();
}
}
// awesome game using chase cameras
class Game1 : GameBase
{
public override CameraBase CameraBase
{
get { return Camera; }
set { Camera = (ChaseCamera)value; }
}
public ChaseCamera Camera { get; set; }
public Game1()
{
Camera = new ChaseCamera();
}
public override void Play()
{
Console.WriteLine("Game.Camera is null? {0}", Camera == null);
Camera.SpecialChaseCameraMethod();
base.Play();
}
}
Solution #2: Inheritance, Injection, and a Twist
This "pattern" might have a real name, but I don't know it. It's very similar to Parallel Hierarchies (as well as my original example) except I'm injecting the camera through the constructor and using the base properties (with casting) for access. I suppose I could have avoided the injection and do a straight assignment to the base property as well (but why avoid injection? It's so useful!). The twist is simply the required casting for the properties. It's not clean, but it's not ugly either. This is my current preferred solution.
CODE
// must inject the camera for this solution
static void Main(string[] args)
{
new Game1(new ChaseCamera()).Play();
Console.ReadLine();
}
// abstract game
abstract class GameBase
{
public virtual CameraBase Camera { get; set; }
public GameBase(CameraBase camera) // injection
{
Camera = camera;
}
public virtual void Play()
{
Console.WriteLine("GameBase.Camera is null? {0}", Camera == null);
if (Camera != null)
Camera.SpecialCameraBaseMethod();
}
}
// awesome game using chase cameras
class Game1 : GameBase
{
public new ChaseCamera Camera
{
get { return (ChaseCamera)base.Camera; }
set { base.Camera = value; }
}
public Game1(ChaseCamera camera) : base(camera) { } // injection
public override void Play()
{
Console.WriteLine("Game.Camera is null? {0}", Camera == null);
Camera.SpecialChaseCameraMethod();
base.Play();
}
}
Both of these solutions give me the desired results with an acceptable implementation.
class Foo : FooBase
{
public override BarBase 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?
}
}
You may try this: change Property type to BarBase and use override. Then use polimorphism to assign a derived class Bar object to the BarBase Property. Property Bar is virtual so the right object will be returned.
Heres a tip for solution:
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<T> where T : CameraBase, new()
{
public T Camera { get; set; }
public GameBase()
{
Camera = new T();
}
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<ChaseCamera>
{
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<FlightCamera>
{
public override void Play()
{
Console.WriteLine("Game.Camera is null? {0}", Camera == null);
Camera.SpecialFlightCameraMethod();
base.Play();
}
}
}
Hope you find this useful.
-Zsolt
Related
I'm having troubles thinking of the design for my assignment.
for the assignment I would have 2 inheritance hierarchies and I would need to mimic multiple inheritance functionalities and the cross product so robotDog, robotBigDog, robotSmallDog, attackRobotDog, etc... it seems just doing multiple inheritance would end up being 9 different class files which is probably not the best approach.
for instance:
public class dog{
public virtual void bark{ Console.WriteLine("woof")};
}
public class bigDog : dog{
public override void bark{ Console.WriteLine("WOOF")};
}
public class smallDog : dog{
public override void bark{ Console.WriteLine("arf arf")};
}
public class robot{
public virtual void action{ Console.WriteLine("moves")}
}
public class attackRobot : robot{
public virtual void action{ Console.WriteLine("attacks")}
}
public class serviceRobot : robot{
public virtual void action{ Console.WriteLine("serves")}
}
I was instead thinking of doing a double composition of one class containing a dog and a robot because smallDog and bigDog can stand in for dog and attackRobot and serviceRobot can stand in for robot.
public class robotDog{
dog myDog;
robot myRobot;
public robotDog(dog typeDog, robot typeRobot){
myDog = typeDog;
myRobot = typeRobot;
}
.
. various functionality
.
}
is it a practical design to use double composition and also have a constructor that ask for a dog and robot? Or is there a different way to think/approach this?
You can not have multiple inheritance in C#, but you can have multiple interfaces.
You can use interfaces to define what a dog and a robot look like, create some different flavours of dog and robot, then combined them into a RobotDog class that has some defaults that can be overridden, i.e.
using System;
namespace ConsoleApp1
{
public interface IDog
{
void bark();
}
public interface IRobot
{
void action();
}
public class dog : IDog
{
public virtual void bark() { Console.WriteLine("woof"); }
}
public class bigDog : dog
{
public override void bark() { Console.WriteLine("WOOF"); }
}
public class smallDog : dog
{
public override void bark() { Console.WriteLine("arf arf"); }
}
public class robot : IRobot
{
public virtual void action() { Console.WriteLine("buzz, click"); }
}
public class attackRobot : robot
{
public override void action() { Console.WriteLine("attacks"); }
}
public class serviceRobot : robot
{
public override void action() { Console.WriteLine("attacks"); }
}
public interface IRobotDog : IDog, IRobot
{
IDog dog { get; set; }
IRobot robot { get; set; }
}
public class RobotDog : IRobotDog
{
public IDog dog { get; set; }
public IRobot robot { get; set; }
public RobotDog()
{
dog = new dog();
robot = new robot();
}
public RobotDog(IDog dogType)
{
dog = dogType;
robot = new robot();
}
public RobotDog(IRobot robotType)
{
dog = new dog();
robot = robotType;
}
public RobotDog(IDog dogType, IRobot robotType)
{
dog = dogType;
robot = robotType;
}
public void bark() { dog.bark(); }
public void action() { robot.action(); }
}
class Program
{
static void Main(string[] args)
{
RobotDog robotDog = new RobotDog();
robotDog.bark();
robotDog.action();
robotDog = new RobotDog(new bigDog(), new attackRobot());
robotDog.bark();
robotDog.action();
robotDog = new RobotDog(new bigDog());
robotDog.bark();
robotDog.action();
robotDog = new RobotDog(new attackRobot());
robotDog.bark();
robotDog.action();
robotDog = new RobotDog();
robotDog.dog = new bigDog();
robotDog.bark();
robotDog.action();
}
}
}
I would like to expand just a bit from what Xavier has offered. An interface is nothing more than a "contract". In its simplest form, any class that inherits an interface MUST declare the functions / methods / properties within it. So this way, any other object attempting to rely on its defined exposed components knows that it can, and they wont be missing. Now, you as the developer can implement that however you want and even have an empty function, provided the function actually exists but otherwise does nothing.
public interface IDog
{
void bark();
}
public interface IRobot
{
void action();
}
First, just simple dog or robot. Notice each implements their respective "REQUIRED" methods from the interface.
public class Dog : IDog
{
public void bark()
{
Console.WriteLine("Woof");
}
}
public class Robot : IRobot
{
public void action()
{
Console.Write("Activate jet pack, fly");
}
}
Notice below, the robotic dog never has an actual Dog or Robot class of its own. However, it DOES implement both individual requirements of each interface respectively into one major class of both.
public class RoboticDog : IDog, IRobot
{
public void bark()
{
Console.WriteLine("Woof -beep- woof");
}
public void action()
{
Console.Write("Activate jet pack, flying with fur");
}
}
Now, lets see how they operate individually.
static void Main(string[] args)
{
object testDog = new Dog();
object testRobot = new Robot();
object testBoth = new RoboticDog();
WhatCanIDo(testDog);
WhatCanIDo(testRobot);
WhatCanIDo(testBoth);
}
public void WhatCanIDo( object theThing )
{
// Here I am checking if the object is of a class type
// the inherits from IDog. If so, I can type-cast it as such
// and then call its "bark()" method as required to exist from interface.
if (theThing is IDog)
((IDog)theThing).bark();
// likewise if the object has interface of an IRobot
if (theThing is IRobot)
((IRobot)theThing).action();
}
I created a small console application for you with some small tips on how to catch when you need an interface over a base class, or vice-versa.
using System;
namespace ConsoleApp6
{
class Program
{
interface IWalkable
{
void Walk(int xAxis, int yAxis);
}
class Robot : IWalkable
{
public int RobotId { get; set; }
public Robot(int robotId)
{
RobotId = robotId;
Console.Write("Robot created! \n");
}
public void Walk(int xAxis, int yAxis)
{
Console.WriteLine("Im walking beep boop");
Console.WriteLine("*walks*");
Console.WriteLine($"Ended up in X: {xAxis} y:{yAxis}");
}
}
class BadRobot : Robot
{
public BadRobot(int robotId) : base(robotId)
{
}
}
class Dog : IWalkable
{
public Dog()
{
Console.Write("Dog created! \n");
}
public void Walk(int xAxis, int yAxis)
{
Console.WriteLine("Im walking, roof roof");
Console.WriteLine("*walks*");
Console.WriteLine($"Ended up in X: {xAxis} y:{yAxis}");
}
public virtual void Breath()
{
Console.WriteLine("I breath normal");
}
}
class BadDog : Dog
{
public override void Breath()
{
Console.WriteLine("I breath normal");
Console.WriteLine("But then I bark, because im bad");
}
//I can't "extend" an interface
//but I can extend a virtual method from the base class
}
static void Main(string[] args)
{
//three tips over inheritance
//1. If you want to abstract some *behavior*, you probably want an interface:
//for example here, both dogs and robots can walk. They are going to do that
//on their own way, so each need their own proper implementation,
//but the actions is the same thus, the interface
// An interface is meant to group objects over shared functionality
//so for example I can later do something like this
var dog = new Dog();
var badDog = new BadDog();
var badRobot = new BadRobot(1);
// these function doesn't care if its a dog or a robot
void WalkOverThere(IWalkable walkable)
{
//some other code...
walkable.Walk(5, 10);
}
//The key here is that the object pass over parameter implements the IWalk interface
WalkOverThere(badDog);
WalkOverThere(badRobot);
//Please notice that for each class that inherits "IWalkable"
//There will be a new implementation, so in this case, if
//all the robots inherit from the class robot, all will walk the same way
//In that, I cannot extend, or modify how that method is performed in the base
//class from the child class
//2. Now, the case is different when we talk about some functionality that could change
//for any child implementation of the base class. Think about the breath functionality
//A robot can't breathe, but a dog does. And given that every dog breaths differently
//it makes sense to create and virtual method, that means that I can reconfigure how
//the breath method behaves. For example:
dog.Breath();
badDog.Breath();
//3. Another thing that is useful to take into account is that
//whenever I can't create a given object without some piece of information,
//it makes sense to create the necessity of that data in the constructor.
//take for example in this code that I cannot create a robot without a valid int robotId
//This practice enforces me to create a robot like:
//var robot = new Robot(100); where 100 is the id
//var robot = new Robot(); the compile would not allow that
}
}
}
Let's say I have an ai or player, I want him to be able to use different weapons.
My design with weapons:
public class Weapon()
{
public virtual void FireWeapon(){} // this is useless for melee weapons
public virtual void SwingMelee(){} // this is useless for guns
public virtual void Reload(){} // this is also useless for melee weapons
}
Then in the ai controller class I simply call the function I want him to do.
This is where the ugly part is (I think)...
Controller class have a list containing some different weapons of ai and a weapon which is being used.
public class WeaponController
{
private List<Weapon> someWeapons;
private Weapon aWeapon;
public void Main()
{
if(/*"Some action or a button click" &&*/ aWeapon.CanSwingMelee() )
aWeapon.SwingMelee();
if(/*"Some action or a button click" &&*/ aWeapon.CanReload() )
aWeapon.Reload();
}
}
What is the better way to implement this? do you have any advices?
Seems that for every different action in a new weapon, I need to implement a function in the most parent Weapon class and I don't think it's a good idea...
The capability of an in-game object can be represented by an interface; you can check if a capability is present by attempting to cast to the interface. What's more, these interfaces can overlap, e.g. both melee and ranged weapons might both have an Attack method.
So for example:
public interface IWeapon
{
void Attack();
}
public interface IRangedWeapon
{
bool IsInRange(ITargetable target);
}
public interface IRequiresAmmunition
{
void Reload();
int AmmoRemaining { get; set; }
}
public class Sword : IWeapon
{
public virtual void Attack() { //code }
}
public class Rifle : IWeapon, IRequiresAmmunition, IRangedWeapon
{
public virtual void Attack() { //code }
public virtual void Reload() { //code }
public virtual int AmmoRemaining { get { } set { } }
public virtual bool IsInrange (ITargetable target) { //code }
}
public class LaserGun: IWeapon, IRangedWeapon
{
public virtual void Attack() { //code }
public virtual bool IsInrange (ITargetable target) { //code }
}
public class WeaponController
{
private List<IWeapon> someWeapons;
private IWeapon aWeapon;
private ITargetable currentTarget;
public void Weapon_OnUse()
{
if (!currentTarget.IsHostile) return;
if (this.IsInMeleeRange(currentTarget))
{
aWeapon.Attack();
return;
}
var w = aWeapon as IRangedWeapon;
if (w != null && w.IsInRange(currentTarget)
{
aWeapon.Attack();
return;
}
context.HUD.Warn("Out of range");
}
public void Weapon_OnReload()
{
var w = aWeapon as IRequiresAmmunition;
if (w != null)
{
w.Reload();
context.HUD.DisplayAmmo(w.AmmoRemaining);
}
}
}
This seems like what abstract classes and inheritance is for:
public abstract class Weapon {
public abstract void Attack();
public abstract void Reload();
}
public class MeleeWeapon : Weapon {
public override void Attack() {
// swing sword
}
public override void Reload() {
// ignore reload
}
}
public class GunWeapon : Weapon {
public override void Attack() {
// fire gun
}
public override void Reload() {
// load weapon from inventory
}
}
public class WeaponController {
private List<Weapon> someWeapons;
private Weapon aWeapon;
public void Main() {
if (/*"Some action or a button click" */)
aWeapon.Attack();
else if (/* some other button click */)
aWeapon.Reload();
}
}
I don't recommend an approach that requires you to create new interfaces for every new behavior and check the type of the weapon. What about something like this:
(This is a very rough draft.)
public abstract class Weapon
{
protected Weapon(WeaponCommandStrategy[] commandStrategies)
{
CommandStrategies = commandStrategies;
}
protected IEnumerable<WeaponCommandStrategy> CommandStrategies { get; }
public void Use(WeaponCommand command)
{
var strategy = CommandStrategies.FirstOrDefault(c => c.Command == command);
strategy?.Execute();
}
}
public enum WeaponCommand
{
Fire,
Swing,
Reload
}
public abstract class WeaponCommandStrategy
{
public WeaponCommand Command { get; private set; }
protected WeaponCommandStrategy(WeaponCommand command)
{
Command = command;
}
public abstract void Execute();
}
Now you can give a weapon whatever behaviors you want it to have in the form of various instances of WeaponCommandStrategy. If a command is sent to a weapon, it executes it. If it doesn't support a command it ignores it. You could add a property to a weapon exposing the available commands so that you could display a list of available commands.
public class Sword : Weapon
{
// Perhaps use dependency injection here
public Sword()
: base(new WeaponCommandStrategy[] { new SwordSwingStrategy() })
{
}
}
public class SwordSwingStrategy : WeaponCommandStrategy
{
public SwordSwingStrategy() : base(WeaponCommand.Swing) { }
public override void Execute()
{
// Do whatever it does
}
}
This essentially makes a Weapon a composition of various things that a weapon can do. If several weapons behave similarly they can share strategies vs. having code duplicated between various weapons.
is this possible to somehow, have this scenario, where A.N inherits code from A with this code example?
The reason for setting it up like this, is that I need multiple classes that inherit from Base<TType> and the Nested : Base<TType> where the server has the base only, and the client has the extended Nested. This way, it would be easy to use the code, where they would have some shared code between themselves & each other.
The problem is that I would have to write identical code inside the
A and A.N
B and B.N
C and C.N
etc.
I have solved this temporarily, by replacing the Nested abstract class, with an Interface and doing
A.N : A, INested, but now I have to rewrite the Base<TType>.Nested code again inside all the Nested classes. For now, the nested class is small & managable.
hope this isn't a confusing question...
public abstract class Base<TType> where TType : class
{
public TType data;
internal void CommonCodeForAll() { }
public abstract void Update();
public abstract class Nested : Base<TType>
{
public abstract void Input();
}
}
public class A : Base<someClass>
{
public float Somevariable;
public void SpecificFunctionToA() { }
public override void Update()
{
// code that gets executed on server & client side that is unique to A
}
public class N : A.Nested
{
public override void Input()
{
if (data.IsReady()) { Somevariable *= 2; }
SpecificFunctionToA();
}
}
}
public class B : Base<anotherClass>
{
public float Somevariable;
public int index;
public int[] Grid;
public void SomethingElse() { }
public override void Update()
{
// code that gets executed on server & client side that is unique to B
}
public class N : B.Nested
{
public override void Input()
{
if (Grid[index] == -1) { SomethingElse(); }
data.Somevariable = Grid[index];
}
}
}
Edit:
I updated the code example to show what I'm trying to achieve.
Why I am trying to do this, is to keep the physics, networking & User input seperate.
There are multiple different controllers where each one has their own pack & unpacking functions, controller identity & access to the physics engine.
I have a solution using ecapsulation of classes instead of inheritance.
public abstract class BaseGeneric<T>
{
T data;
// ctor
protected BaseGeneric(T data)
{
this.data=data;
}
// methods
public abstract void Update();
// properties
public T Data
{
get { return data; }
set { data=value; }
}
// base nested class
public abstract class BaseNested<B> where B : BaseGeneric<T>
{
protected B #base;
// ctor
protected BaseNested(B #base)
{
this.#base=#base;
}
// methods
public abstract void Input(T data);
public void Update() { #base.Update(); }
// properties
public T Data
{
get { return #base.data; }
set { #base.data=value; }
}
}
}
// implementation base
public class Base : BaseGeneric<int>
{
// ctor
protected Base(int data) : base(data) { }
//methods
public override void Update()
{
this.Data+=1;
}
// implemented nested class
public class Nested : Base.BaseNested<Base>
{
// ctor
public Nested(int data) : base(new Base(data)) { }
public Nested(Base #base) : base(#base) { }
// methods
public override void Input(int data)
{
this.Data=data;
}
}
}
class Program
{
static void Main(string[] args)
{
// new implemented class with value 0
var nested=new Base.Nested(0);
// set value to 100
nested.Input(100);
// call update as implemented by `Base`.
nested.Update();
}
}
public abstract class State<T>
{
public virtual Enter(T item)
{
// an empty method
}
}
public class ChaseState : State<FieldPlayer>
{
public override Enter(Player pl)
{
// ...
pl.Fsm.CurrentState = ChaseState.Instance;
//...
}
}
public class TendGoal : State<Goalkeeper>
{
public override Enter(Goalkeeper gk)
{
// ...implementation
gk.Fsm.CurrentState = TendGoal.Instance;
// ...implementation
}
}
public class DefendState : State<Team>
{
public override Enter(Team team)
{
// ....
team.Fsm.CurrentState = DefendState.Instance;
//.....
}
}
"Goalkeeper" and "FieldPlayer" inherit from an abstract class "Player", while "Team" inherits from another class.
public class FSM
{
public /*some type*/ owner; // PROBLEM 1
// OWNER CAN BE TEAM, GOALKEEPEEPER
// OR FIELD PLAYER
public /*some type*/ globalState;
public /*some type*/ currentState;
public /*some type*/ previousState;
public void Update()
{
if (globalState != null)
{
globalState.Execute(owner); // PROBLEM 2
// IF GLOBAL STATE'S TYPE
// IS AN OBJECT, CANT CALL EXECUTE
// OBJECTS TYPE WILL BE KNOWN ONLY
// DURING RUNTIME
}
}
}
Each object of type "Goalkeeper", "FieldPlayer" and "Team" will have a State Machine instance. The problem is.. generics cant be properties.
What should I do ?
If you make State an ordinary interface, not generic, and have its Enter method take another interface that your teams, goalkeeprs, players, etc all implement (it can even just be empty), it ought to work.
public interface IOwner {}
public interface IState
{
void Enter(IOwner item);
}
public class ChaseState : IState
{
public void Enter(IOwner pl)
{
// ...
//...
}
}
public class Player :IOwner { }
public class Something {
IOwner owner = new Team();
IState globalState = new ChaseState();
IState currentState = new DefendState();
public void Update()
{
if (globalState != null)
{
globalState.Enter(owner);
}
else if (currentState != null)
{
currentState.Enter(owner);
}
}
}
After reading your code some more, an Abstract Class is unnecessary here. You should convert State to an interface, ex: IState and remove the generic signature from it. Then your properties in your FSM object can all be public IState globalState, etc..
I have two projects: ClientProj and ServerProj, which both share a SharedLibrary containing the basics of my game.
Inside this library I have the class GameObject which is the base class from which many other game items inherit.
Inside GameObject is a SetPosition() method.
Here's my problem: When I run SetPosition() on the client, I wish to add some additional code / override the method completely. The code I wish to add however relates to classes that are only present in the ClientProj namespace, which the SharedLibrary knows nothing about.
Is there any clean way to override or extend the library methods?
Updated: Note that the instances of GameObject and all things that inherit it are defined, contained and handled all within the SharedLibrary namespace. For the most part the ClientProj and ServerProj only handle networking, users and input/output.
You can use the Proxy pattern and have the game objects inherit from the proxy class instead of the real class:
SharedLibrary:
public class GameObject
{
public virtual void SetPosition() { ... }
}
public class DelegatingGameObject : GameObject
{
public GameObject Inner;
public override void SetPosition() { Inner.SetPosition(); }
}
public class Tree : DelegatingGameObject
{
}
ClientLibrary:
class ClientGameObject : GameObject
{
public override void SetPosition()
{
if (isMonday) base.SetPosition();
}
}
var tree = new Tree { Inner = new ClientGameObject() };
tree.SetPosition();
SharedLibrary:
public class GameObject
{
public virtual void SetPosition() { Console.WriteLine("GameObject.SetPosition"); }
public static event Func<GameObject> Factory;
internal static GameObject CreateBase() { var factory = Factory; return (factory != null) ? factory() : new GameObject(); }
}
internal class GameObjectBase : GameObject
{
private readonly GameObject baseGameObject;
protected GameObjectBase() { baseGameObject = GameObject.CreateBase(); }
public override void SetPosition() { baseGameObject.SetPosition(); }
}
internal class Tree : GameObjectBase
{
public override void SetPosition()
{
Console.WriteLine("Tree.SetPosition");
base.SetPosition();
}
}
public static class Game
{
public static void Start()
{
new Tree().SetPosition();
}
}
ClientLibrary:
internal class ClientGameObject : GameObject
{
public override void SetPosition()
{
Console.WriteLine("ClientGameObject.SetPosition Before");
base.SetPosition();
Console.WriteLine("ClientGameObject.SetPosition After");
}
}
internal static class Program
{
static void Main(string[] args)
{
GameObject.Factory += () => new ClientGameObject();
Game.Start();
}
}
Make SetPosition method virtual and use override keyword to override its behaviour in ClientProj.
You can do it virtual in base class, override in derived, and in overriden method call your methods and after base class method.
A psudocode can look like this:
public class GameObject
{
public virtual void SetPosition()
{
//do something here
}
}
public class Derived: GameObject
{
public override void SetPosition()
{
// do something specific to Derived
base.SetPosition(); // CALL BASE CLASS METHOD AFTER
}
}