Force a child class to initialise a parent property after computation - c#

I have a child class Bicycle that inherits from Agent. The agent has a property which depends on the bicycle to define it. Namely, the physics model for the agent needs to be initialised with the velocity and acceleration constraints which are defined on a per-bicycle-basis and would be different for another type of agent.
The problem I have is that I cannot pass the parameters I need to calculate (the velocity/acceleration require calculations to draw them from a theoretical distribution) for this in the base() constructor because of course the child class hasn't yet been instantiated.
The calculations are done once per bicycle instance but are used multiple times so a simple static method won't do the job. I can just call a protected method in the parent after they're calculated but AFAIK there's no way to enforce this in the child, or more particularly in any future children which I might not write.
So for example, I could:
public abstract class Agent
{
protected IPhysics PluginPhysics { get; set; }
protected Agent(...)
{
}
}
public class Bicycle : Agent
{
private double maxA;
public Bicycle(Object anotherParameter) : base(...)
{
maxA = ComputationOfMaxA();
this.PluginPhysics = new Physics(anotherParameter, maxA);
}
private static double ComputationOfMaxA()
{
...
}
...
}
or I could:
public abstract class Agent
{
protected IPhysics PluginPhysics { get; private set; }
protected Agent(...)
{
}
protected void SetupPhysics(Physics physics)
{
this.PluginPhysics = physics;
}
}
public class Bicycle : Agent
{
private double maxA;
public Bicycle(Object anotherParameter) : base(...)
{
maxA = ComputationOfMaxA();
SetupPhysics(new Physics(anotherParameter,maxA));
}
private static double ComputationOfMaxA()
{
...
}
...
}
I'd rather not do either of those as there's no compile-time way to ensure that the child initialises PluginPhysics that I can think of, and I'd rather PluginPhysics not be able to be changed once it's been initialised. I'd also rather not have the parts of the parameters that need to go into Physicsoutside the Bicycle class. I appreciate that all these things might not be simultaneously possible.
So short of strongly worded documentation or a bunch of run-time null checks in the parent class before any of the relevant class objects are called on, is there an obvious C#-ish way I'm missing of forcing a child to initialise a parent class field before use if you can't do it in the constructor?

d4Rk's answer was very close, however you should try not call virtual methods from a constructor as bad things can happen. However if you use a combination of Lazy loading tricks and ISupportInitialize you can defer the creation of the plugin till after the constructor is finished.
public abstract class Agent : ISupportInitialize
{
private bool _initialized = false;
private IPhysics _pluginPhysics;
protected IPhysics PluginPhysics
{
get
{
if(!_initialized)
EndInit();
return _pluginPhysics;
}
}
protected Agent(...)
{
}
protected abstract IPhysics CreatePhysics();
ISupportInitialize.BeginInit()
{
//We make this a explicit implementation because it will not
//do anything so we don't need to expose it.
}
public void EndInit()
{
if(_initialized)
return;
_initialized = true;
_pluginPhysics = CreatePhysics();
}
}
public class Bicycle : Agent
{
private double maxA;
Object _anotherParameter;
public Bicycle(Object anotherParameter)
{
_anotherParameter = anotherParameter;
}
protected override IPhysics CreatePhysics()
{
ComputationOfMaxA();
return new Physics(anotherParameter, maxA);
}
}
The user of your class will need to call EndInit() after they get a object back to cause the IPhysics object to be created, however if they forget to call the initialize function the getter on the physics object will trigger the initialize call itself the first time it is used.
You could do everything I have shown without the ISupportInitialize interface and just having a public Initalize() method on the base class but I like to expose framework interfaces when they fit.

What about enforcing the subclass to implement a CreatePhysics method, and call this in the base ctor?
Like this:
public abstract class Agent
{
protected IPhysics PluginPhysics { get; private set; }
protected Agent(...)
{
var physics = CreatePhysics();
SetupPhysics(physics);
}
void SetupPhysics(IPhysics physics)
{
this.PluginPhysics = physics;
}
protected abstract IPhysics CreatePhysics();
}
public class Bicycle : Agent
{
private double maxA;
protected override IPhysics CreatePhysics()
{
ComputationOfMaxA();
return new Physics(maxA);
}
}

How about making the constructor for Agent take the IPhysics object and making it protected Then in your Bicycle class, you are forced to call the constructor on the base which sets up your class property:
public class Agent
{
protected IPhysics PluginPhysics { get; private set; }
protected Agent(IPhysics physicsPlugin)
{
PluginPhysics = physicsPlugin;
}
}
public class Bicycle : Agent
{
public Bicycle(IPhysics physicsPlugin)
: base(physicsPlugin)
{
Console.WriteLine("Bicycle ctor");
}
}

Related

C# call method before override method

Good day,
I have a base class with a virtual method that needs to be overridden per implementation, but I would like to call the base method first before overriding.
Is there a way to accomplish this without having to actually call the method.
public class Base
{
public virtual void Method()
{
//doing some stuff here
}
}
public class Parent : Base
{
public override void Method()
{
base.Method() //need to be called ALWAYS
//then I do my thing
}
}
I cannot always rely that the base.Method() will be called in the override, so I would like to enforce it somehow. This might be a design pattern of some kind, any approach to accomplish the result will do.
One way is to define a public method in the base class, which calls another method that can be (or must be) overridden:
public class Base
{
public void Method()
{
// Do some preparatory stuff here, then call a method that might be overridden
MethodImpl()
}
protected virtual void MethodImpl() // Not accessible apart from child classes
{
}
}
public class Parent : Base
{
protected override void MethodImpl()
{
// ToDo - implement to taste
}
}
You can use the decorator design pattern, applying this pattern you can attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality:
public abstract class Component
{
public abstract void Operation();
}
public class ConcreteComponent1 : Component
{
public override void Operation()
{
//logic
}
}
public abstract class ComponentDecorator : Component
{
protected readonly Component Component;
protected ComponentDecorator(Component component)
{
Component = component;
}
public override void Operation()
{
if(Component != null)
Component.Operation();
}
}
public class ConcreteDecorator : ComponentDecorator
{
public ConcreteDecorator(Component component) : base(component)
{
}
public override void Operation()
{
base.Operation();
Console.WriteLine("Extend functionality");
}
}
Hope this helps!

How to implement class structure reasonable

I hope my question is legit because i'm not really used to all the hierarchical class structs.
I try to encapsulate a class that delivers the same functions for two different cameras connected to device. Those functions are thought to be within the class DeviceObject whilst I want to access those functions by using an instance of Camera1 or Camera2. Here's some pseudo code that might not work:
public class Camera1 : DeviceObject
{
public Generic.CameraSelect Camera { get; set; } = Generic.CameraSelect.CAM1;
}
public class Camera2 : DeviceObject
{
public Generic.CameraSelect Camera { get; set; } = Generic.CameraSelect.CAM2;
}
public class DeviceObject
{
public void SomeFunction()
{
HardwareDriver.Function(SelectedCamera);
}
}
What I want is to easly access the methods of DeviceObject dependend on the Camera-Class:
public void Method()
{
Camera1 Cam1 = New Camera1();
Camera2 Cam2 = New Camera2();
Cam1.SomeFunction();
Cam2.SomeFunction();
}
I apologize if this is a stupid question but after 7 hours of programming I'm completely stuck and don't get it in my head anymore :)
UPDATE:
I have implemented - as entirely all of you have recommended - an abstract base class and derivate the Camera Objects as member of the base class.
What I didn't know so far, that it's possible to cast derived classes to the type of base classes. That was absolutely new to me but helped me a looot! with my implementation.
So thanks to all of you who helped me without minusing me to hell :)
Why not use an abstract class?
public class Camera1 : Camera
{
public override Generic.CameraSelect CameraType { get; set; } = "CAM1";
}
public class Camera2 : Camera
{
public override Generic.CameraSelect CameraType { get; set; } = "CAM2";
}
public abstract class Camera
{
public abstract Generic.CameraSelect CameraType { get; set; }
public void SomeFunction()
{
HardwareDriver.Function(this);
}
}
You typically only use inheritance when you need different implementation (methods). If the implementation is the same for both cameras but the data involved is different, you can use one class and a factory to "create" a camera with the appropriate settings.
public class CameraFactory
{
public static Camera1 {
get {
return new Camera {Camera = Generic.CameraSelect.CAM1};
}
public static Camera2 {
get {
return new Camera {Camera = Generic.CameraSelect.CAM2};
}
}
That's not the only way to do it, but it is one way.
Also note that if the Camera property should not change then make it get-only (or at worst use a private setter.
As other people have suggested, the answer to your question is probably to add an abstract / override:
public class Camera1 : Camera
{
public override Generic.CameraSelect CameraType { get; set; } = "CAM1";
}
public class Camera2 : Camera
{
public override Generic.CameraSelect CameraType { get; set; } = "CAM2";
}
public abstract class Camera
{
public abstract Generic.CameraSelect CameraType { get; set; }
public void SomeFunction()
{
HardwareDriver.Function(this);
}
}
However, I was triggered by the HardwareDriver class. There are two points I'd like to make here:
Drivers work on capabilities, not on names. If you're goal is decomposition, you might want to go for a double dispatch that calls stuff depending on the scope.
What's the purpose of a camera and why is it modelled the way 'the world' works?
Double dispatch
Let's start with the double dispatch. The way I see it, you'll probably end up with a large 'switch' block somewhere that incorporates the logic. That doens't make a lot of sense to me. Basically you probably attempt to decouple the objects from the logic -- so let's use inheritance to do that. In this case, it'll work like this:
public class Camera1 : Camera
{
public override void SomeFunction(IDeviceVisitor driver)
{
// Very simple camera:
driver.HandleAngle(this, 12.0);
driver.GenerateModel();
}
}
public class Camera2 : Camera
{
public override void SomeFunction(IDeviceVisitor driver)
{
// This camera understands focus
driver.HandleAngle(this, 12.0);
driver.HandleFocus(this, focus, this.focus * 1.2);
driver.GenerateModel();
}
}
public class SomeHardwareDriver : IDeviceVisitor { ... }
public interface IDeviceVisitor
{
void HandleFocus(Camera camera, double focusValue, double realDistance);
void HandleAngle(Camera camera, double angle);
void GenerateModel();
// [...]
// etc
}
public abstract class Camera
{
public abstract void SomeFunction(IDeviceVisitor driver);
}
The reason I pass this along is because you might want to call another camera function from within the HardwareDriver to do the magic.
Modelling in the way the world works
If two camera have nothing with each other in common, don't give them a common base class. It makes no sense.
Or the more general rule: always remember that a class model doesn't need to make sense to you as a person; it has to make sense to a computer.
How to know when you're running the wrong way
2 clues:
If you end up with large switch blocks, a lot of if-then-else's, etc -- then you're probably doing it wrong.
If you copy-paste code, you're probably doing it wrong.
You can have a encapsulating method which accepts a parameter of DeviceObject like
public void CallSomeFunction(DeviceObject dobj)
{
dobj.SomeFunction();
}
Then you can create an instance of any of camera base type and call the method
Camera1 Cam1 = New Camera1();
CallSomeFunction(cam1);

Object Oriented Programming correct use interface

I'm trying to design a few classes for a game, but I'm not sure I'm doing it right.
I have two classes: Actor and Building.
These have a few subclasses: Policeman, Fireman and PoliceStation, FireStation.
I want to be able to put all these items together in a list to iterate through later, so I've added a base class: GameEntity.
So what I have is this:
public abstract class GameEntity:
{
public GameEntity()
{
}
}
public class Actor: GameEntity
{
public int _speed;
public TileSprite _UI;
public Actor()
{
}
public bool CollidesWith(Vector2 pos)
{
//Do stuff here
}
public virtual void OnClick()
{
//Do stuff here
}
public void DoActing()
{
}
}
public class Policeman: Actor
{
public Policeman()
{
_speed = 10;
}
public override void OnClick()
{
//Do stuff
}
}
public class Building: GameEntity
{
public TileSprite _UI;
public Building()
{
}
public bool CollidesWith(Vector2 pos)
{
//Do stuff here
}
public virtual void OnClick()
{
//Do stuff here
}
public void DoBuilding()
{
}
}
public class PoliceStation: Building
{
public PoliceStation()
{
}
public override void OnClick()
{
//Do stuff
}
}
Now, I want to be able to do this:
List<GameEntity> Entities = new List<GameEntity>();
Actor a1 = new PoliceMan();
Building b1 = new PoliceStation
Entities.Add(a1);
Entities.Add(b1);
foreach(GameEntity ent in Entities)
{
if (ent.CollidesWith(something))
{
ent.OnClick();
//If Actor then do
ent.DoActing();
//If Building then do
ent.DoBuilding();
}
}
Now, in order to do the last bit, would it be best if I implement an interface that contains the OnClick and CollidesWith, or can I do it with inheritance?
If so, how would I do this?
Cheers.
This is only to give you the idea, I guess that's what you need.
public interface IGameEntity
{
bool CollidesWith();
void OnClick();
void DoActing();
}
public class Actor : IGameEntity { //Interface implemented }
public class Building: IGameEntity { //Interface implemented }
public class Policeman: IGameEntity { //Interface implemented }
public class Fireman: IGameEntity { //Interface implemented }
public class FireStation: IGameEntity { //Interface implemented }
In your client object just do something like this:
List<IGameEntity> entities = new List<IGameEntity>()
{
new Actor(),
new Building(),
new Policeman(),
new Fireman(),
new Fireman()
};
foreach (IGameEntity entity in entities)
{
entity.CollidesWith();
entity.OnClick();
entity.DoActing();
}
Number of ways to go here.
If all GameEntities can be clicked on then you could add an OnClick event property to the base class.
If Not then I'd have an Interface IClick and then implement that on clickable entities.
Collision, depends.
Building don't move about so they can't collide with anything, but they can be collided with and so for instance you might want do a damage rountine, which then suggests a destroyed, routine a repair routine maybe.
There's no right answer, but
Three code smells would be a
A Base class with nothing in it.
A very deep inheritance hierarchy (more than two levels is cause for suspicion in my book)
So if you start seeing GameEntity -> BuildingEntity -> ActiveBuildingEntity -> RepairableBuildingEntity, you are in a mess that's about to get messier.
And above all a base class with do nothing methods in it that only exist because you need to add behaviour (override) in some descendants.
Don't be scared about having a few interfaces. IClick, ICollision, IDamage, IRepair etc. It's way better than implying a building can crash into a car.
You could do something like this:
public interface IGameEntity
{
void OnClick();
bool CollidesWith(Vector2 pos);
void Do();
}
public abstract class Actor: IGameEntity
{
public int _speed;
public TileSprite _UI;
public virtual bool CollidesWith(Vector2 pos)
{
//Do stuff here
}
// can be marked virtual with implementation if you want a default
// this way base classes will be forced to implement their own implementation
public abstract void OnClick();
// can be marked virtual with implementation if you want a default
// this way base classes will be forced to implement their own implementation
public abstract void Do();
}
public class Policeman: Actor
{
public Policeman()
{
_speed = 10;
}
public override void OnClick()
{
//Do stuff
}
public override void Do()
{
//Do Acting for Police
}
}
public abstract class Building: IGameEntity
{
public TileSprite _UI;
public bool CollidesWith(Vector2 pos)
{
//Do stuff here
}
public abstract void OnClick();
public abstract void Do();
}
public class PoliceStation: Building
{
public PoliceStation()
{
}
public override void OnClick()
{
//Do stuff
}
public override void Do()
{
// Do Building
}
}
If Game Entity is just an interface then there is no need to make it an abstract class. If Actor and Building can never exist as a stand alone object then they should be abstract. If DoActing, DoBuilding, and OnClick must be overridden by the base classes then you can mark them abstract in actor and Building.
I followed norlesh's suggestion to just have one method Do. You could also make Actor and Building have their own abstract methods and IGameEntity would not have Do. Then you would put an if statement and check the if each object is of type builder then they would run the build and if of type actor then run act.
I think the way of having one method is better, since you eliminate one step. From a design perspective I'm not sure but it feels the same to me either way.
List<IGameEntity> Entities = new List<IGameEntity>();
Actor a1 = new PoliceMan();
Building b1 = new PoliceStation();
Entities.Add(a1);
Entities.Add(b1);
foreach(IGameEntity ent in Entities)
{
if (ent.CollidesWith(something))
{
ent.OnClick();
ent.Do();
}
}
Adding a virtual doStuff() to GameEntity and overriding it in the child classes instead of having unique method names like DoActing and DoBuilding then calling that from your loop should do what you want.

how to initialize field in base class which should be initialized in subclass?

My base class Car contains field engine which can not be initialized in base class. I can initialize it in subclass only, for example in ElectricCar i can write engine = new ElectricEngine. However I use field in base class. So I have a field which used but not initialized:
public class Car {
protected Engine engine;
public void Start() {
engine.Start();
// do something else
}
public void Stop {
engine.Stop();
// do something else
}
public void Diagnose() {
engine.Diagnose();
// anotherField.Diagnose();
// oneAnotherField.Diagnose();
}
}
How to better initialize engine?
Version 1. Field guaranteed to be initialized but with many fields constructor will look ugly. Bug-free but ugly.
public class Car {
protected Engine engine;
public Car(Engine engine) {
this.engine = engine;
}
public void Start() {
engine.Start();
// do something else
}
public void Stop {
engine.Stop();
// do something else
}
public void Diagnose() {
engine.Diagnose();
// anotherField.Diagnose();
// oneAnotherField.Diagnose();
}
}
public class ElectricCar : Car {
public ElectricCar() : base (new ElectricEngine()) {
}
}
Version 2. Subclasses should remember to initialize the field, having such "contract" with subclasses may introduce bugs (uninitialized field).
public class Car {
protected Engine engine;
public Car() {
}
public void Start() {
engine.Start();
// do something else
}
public void Stop {
engine.Stop();
// do something else
}
public void Diagnose() {
engine.Diagnose();
// anotherField.Diagnose();
// oneAnotherField.Diagnose();
}
}
public class ElectricCar : Car {
public ElectricCar() {
engine = new ElectricEngine();
}
}
Version 3. Field guaranteed to be initialized. Constructor is clear. But calling virtual method from constructor (potentially dangerous, not recommended in general).
public class Car {
protected Engine engine;
public Car() {
InitializeEngine();
}
protected abstract void InitializeEngine();
public void Start() {
engine.Start();
// do something else
}
public void Stop {
engine.Stop();
// do something else
}
public void Diagnose() {
engine.Diagnose();
// anotherField.Diagnose();
// oneAnotherField.Diagnose();
}
}
public class ElectricCar : Car {
public ElectricCar() {
}
protected void override InitializeEngine() {
engine = new ElectricEngine();
}
}
So every version has pros and cons. Which version is better? Or probably you can suggest even something else.
Version 3 is sort of a take on the Template method design pattern. If your base class can't provide a reasonable default implementation, but you require every car to have an engine, delegating the creation to the base class is a very appropriate and safe solution. I would slightly adjust your initialization to be something like this:
protected abstract Engine InitializeEngine();
Then in your constructor for Car:
public Car() {
engine = InitializeEngine();
}
This will make the contract very clear. Your subclasses simply need to provide an engine and your base class will guarantee that the engine variable is assigned after the constructor is called.
Another option can be something like:
public class Car {
private Engine engine; //PRIVATE
protected Engine MyEngine { //PROTECTED PROPERTY
get {
if(engine == null)
engine = new Engine();
return engine;
}
}
}
In this way the caller will be safe that will use always initialized member, as it checked inside protected property it can access only, as field is private.
I'd vote for option 1. You're clearly stating in the constructor that every Car must have an Engine, BrakingSystem, ECU, etc. You also know that these have been created before the Car. If you delay the creation of them until first access and there is an issue creating them, then it will be more difficult to handle the exception appropriately.
Then use property instead of field for Engine, because non-private fields are very hard to debug.
About design
For first, you must declare Car as abstract and use IEngine behavior instead of Engine class. Then for any concrete car (i.e. subclass) you can choose appropriate type of injection (by constructor, by property, ...).
public interface IEngine
{
void Start();
void Stop();
void Diagnose();
}
public abstract class Car
{
protected Car(IEngine engine)
{
Engine = engine;
}
protected IEngine Engine {get; set;}
public void Start() {
engine.Start();
// do something else
}
public void Stop() {
engine.Stop();
// do something else
}
public void Diagnose() {
engine.Diagnose();
// anotherField.Diagnose();
// oneAnotherField.Diagnose();
}
}
public class ConcreteCar : Car
{
public ConcreteCar(IEngine engine):base(engine) // injection by constructor
{
}
...
}
Usage:
Car concreteCar = new ConcreteCar(new ConcreteEngine());
EDIT
You can force derived classes to initialize engine. See updated example.

Interface defining a constructor signature?

It's weird that this is the first time I've bumped into this problem, but:
How do you define a constructor in a C# interface?
Edit
Some people wanted an example (it's a free time project, so yes, it's a game)
IDrawable
+Update
+Draw
To be able to Update (check for edge of screen etc) and draw itself it will always need a GraphicsDeviceManager. So I want to make sure the object has a reference to it. This would belong in the constructor.
Now that I wrote this down I think what I'm implementing here is IObservable and the GraphicsDeviceManager should take the IDrawable...
It seems either I don't get the XNA framework, or the framework is not thought out very well.
Edit
There seems to be some confusion about my definition of constructor in the context of an interface. An interface can indeed not be instantiated so doesn't need a constructor. What I wanted to define was a signature to a constructor. Exactly like an interface can define a signature of a certain method, the interface could define the signature of a constructor.
You can't. It's occasionally a pain, but you wouldn't be able to call it using normal techniques anyway.
In a blog post I've suggested static interfaces which would only be usable in generic type constraints - but could be really handy, IMO.
One point about if you could define a constructor within an interface, you'd have trouble deriving classes:
public class Foo : IParameterlessConstructor
{
public Foo() // As per the interface
{
}
}
public class Bar : Foo
{
// Yikes! We now don't have a parameterless constructor...
public Bar(int x)
{
}
}
As already well noted, you can't have constructors on an Interface. But since this is such a highly ranked result in Google some 7 years later, I thought I would chip in here - specifically to show how you could use an abstract base class in tandem with your existing Interface and maybe cut down on the amount of refactoring needed in the future for similar situations. This concept has already been hinted at in some of the comments but I thought it would be worth showing how to actually do it.
So you have your main interface that looks like this so far:
public interface IDrawable
{
void Update();
void Draw();
}
Now create an abstract class with the constructor you want to enforce. Actually, since it's now available since the time you wrote your original question, we can get a little fancy here and use generics in this situation so that we can adapt this to other interfaces that might need the same functionality but have different constructor requirements:
public abstract class MustInitialize<T>
{
public MustInitialize(T parameters)
{
}
}
Now you'll need to create a new class that inherits from both the IDrawable interface and the MustInitialize abstract class:
public class Drawable : MustInitialize<GraphicsDeviceManager>, IDrawable
{
GraphicsDeviceManager _graphicsDeviceManager;
public Drawable(GraphicsDeviceManager graphicsDeviceManager)
: base (graphicsDeviceManager)
{
_graphicsDeviceManager = graphicsDeviceManager;
}
public void Update()
{
//use _graphicsDeviceManager here to do whatever
}
public void Draw()
{
//use _graphicsDeviceManager here to do whatever
}
}
Then just create an instance of Drawable and you're good to go:
IDrawable drawableService = new Drawable(myGraphicsDeviceManager);
The cool thing here is that the new Drawable class we created still behaves just like what we would expect from an IDrawable.
If you need to pass more than one parameter to the MustInitialize constructor, you can create a class that defines properties for all of the fields you'll need to pass in.
A very late contribution demonstrating another problem with interfaced constructors. (I choose this question because it has the clearest articulation of the problem). Suppose we could have:
interface IPerson
{
IPerson(string name);
}
interface ICustomer
{
ICustomer(DateTime registrationDate);
}
class Person : IPerson, ICustomer
{
Person(string name) { }
Person(DateTime registrationDate) { }
}
Where by convention the implementation of the "interface constructor" is replaced by the type name.
Now make an instance:
ICustomer a = new Person("Ernie");
Would we say that the contract ICustomer is obeyed?
And what about this:
interface ICustomer
{
ICustomer(string address);
}
You can't.
Interfaces define contracts that other objects implement and therefore have no state that needs to be initialized.
If you have some state that needs to be initialized, you should consider using an abstract base class instead.
I was looking back at this question and I thought to myself, maybe we are aproaching this problem the wrong way. Interfaces might not be the way to go when it concerns defining a constructor with certain parameters... but an (abstract) base class is.
If you create a base class with a constructor on there that accepts the parameters you need, every class that derrives from it needs to supply them.
public abstract class Foo
{
protected Foo(SomeParameter x)
{
this.X = x;
}
public SomeParameter X { get; private set }
}
public class Bar : Foo // Bar inherits from Foo
{
public Bar()
: base(new SomeParameter("etc...")) // Bar will need to supply the constructor param
{
}
}
It is not possible to create an interface that defines constructors, but it is possible to define an interface that forces a type to have a paramerterless constructor, though be it a very ugly syntax that uses generics... I am actually not so sure that it is really a good coding pattern.
public interface IFoo<T> where T : new()
{
void SomeMethod();
}
public class Foo : IFoo<Foo>
{
// This will not compile
public Foo(int x)
{
}
#region ITest<Test> Members
public void SomeMethod()
{
throw new NotImplementedException();
}
#endregion
}
On the other hand, if you want to test if a type has a paramerterless constructor, you can do that using reflection:
public static class TypeHelper
{
public static bool HasParameterlessConstructor(Object o)
{
return HasParameterlessConstructor(o.GetType());
}
public static bool HasParameterlessConstructor(Type t)
{
// Usage: HasParameterlessConstructor(typeof(SomeType))
return t.GetConstructor(new Type[0]) != null;
}
}
Hope this helps.
One way to solve this problem i found is to seperate out the construction into a seperate factory. For example I have an abstract class called IQueueItem, and I need a way to translate that object to and from another object (CloudQueueMessage). So on the interface IQueueItem i have -
public interface IQueueItem
{
CloudQueueMessage ToMessage();
}
Now, I also need a way for my actual queue class to translate a CloudQueueMessage back to a IQueueItem - ie the need for a static construction like IQueueItem objMessage = ItemType.FromMessage. Instead I defined another interface IQueueFactory -
public interface IQueueItemFactory<T> where T : IQueueItem
{
T FromMessage(CloudQueueMessage objMessage);
}
Now I can finally write my generic queue class without the new() constraint which in my case was the main issue.
public class AzureQueue<T> where T : IQueueItem
{
private IQueueItemFactory<T> _objFactory;
public AzureQueue(IQueueItemFactory<T> objItemFactory)
{
_objFactory = objItemFactory;
}
public T GetNextItem(TimeSpan tsLease)
{
CloudQueueMessage objQueueMessage = _objQueue.GetMessage(tsLease);
T objItem = _objFactory.FromMessage(objQueueMessage);
return objItem;
}
}
now I can create an instance that satisfies the criteria for me
AzureQueue<Job> objJobQueue = new JobQueue(new JobItemFactory())
hopefully this helps someone else out someday, obviously a lot of internal code removed to try to show the problem and solution
One way to solve this problem is to leverage generics and the new() constraint.
Instead of expressing your constructor as a method/function, you can express it as a factory class/interface. If you specify the new() generic constraint on every call site that needs to create an object of your class, you will be able to pass constructor arguments accordingly.
For your IDrawable example:
public interface IDrawable
{
void Update();
void Draw();
}
public interface IDrawableConstructor<T> where T : IDrawable
{
T Construct(GraphicsDeviceManager manager);
}
public class Triangle : IDrawable
{
public GraphicsDeviceManager Manager { get; set; }
public void Draw() { ... }
public void Update() { ... }
public Triangle(GraphicsDeviceManager manager)
{
Manager = manager;
}
}
public TriangleConstructor : IDrawableConstructor<Triangle>
{
public Triangle Construct(GraphicsDeviceManager manager)
{
return new Triangle(manager);
}
}
Now when you use it:
public void SomeMethod<TBuilder>(GraphicsDeviceManager manager)
where TBuilder: IDrawableConstructor<Triangle>, new()
{
// If we need to create a triangle
Triangle triangle = new TBuilder().Construct(manager);
// Do whatever with triangle
}
You can even concentrate all creation methods in a single class using explicit interface implementation:
public DrawableConstructor : IDrawableConstructor<Triangle>,
IDrawableConstructor<Square>,
IDrawableConstructor<Circle>
{
Triangle IDrawableConstructor<Triangle>.Construct(GraphicsDeviceManager manager)
{
return new Triangle(manager);
}
Square IDrawableConstructor<Square>.Construct(GraphicsDeviceManager manager)
{
return new Square(manager);
}
Circle IDrawableConstructor<Circle>.Construct(GraphicsDeviceManager manager)
{
return new Circle(manager);
}
}
To use it:
public void SomeMethod<TBuilder, TShape>(GraphicsDeviceManager manager)
where TBuilder: IDrawableConstructor<TShape>, new()
{
// If we need to create an arbitrary shape
TShape shape = new TBuilder().Construct(manager);
// Do whatever with the shape
}
Another way is by using lambda expressions as initializers. At some point early in the call hierarchy, you will know which objects you will need to instantiate (i.e. when you are creating or getting a reference to your GraphicsDeviceManager object). As soon as you have it, pass the lambda
() => new Triangle(manager)
to subsequent methods so they will know how to create a Triangle from then on. If you can't determine all possible methods that you will need, you can always create a dictionary of types that implement IDrawable using reflection and register the lambda expression shown above in a dictionary that you can either store in a shared location or pass along to further function calls.
The generic factory approach still seems ideal. You would know that the factory requires a parameter, and it would just so happen that those parameters are passed along to the constructor of the object being instantiated.
Note, this is just syntax verified pseudo code, there may be a run-time caveat I'm missing here:
public interface IDrawableFactory
{
TDrawable GetDrawingObject<TDrawable>(GraphicsDeviceManager graphicsDeviceManager)
where TDrawable: class, IDrawable, new();
}
public class DrawableFactory : IDrawableFactory
{
public TDrawable GetDrawingObject<TDrawable>(GraphicsDeviceManager graphicsDeviceManager)
where TDrawable : class, IDrawable, new()
{
return (TDrawable) Activator
.CreateInstance(typeof(TDrawable),
graphicsDeviceManager);
}
}
public class Draw : IDrawable
{
//stub
}
public class Update : IDrawable {
private readonly GraphicsDeviceManager _graphicsDeviceManager;
public Update() { throw new NotImplementedException(); }
public Update(GraphicsDeviceManager graphicsDeviceManager)
{
_graphicsDeviceManager = graphicsDeviceManager;
}
}
public interface IDrawable
{
//stub
}
public class GraphicsDeviceManager
{
//stub
}
An example of possible usage:
public void DoSomething()
{
var myUpdateObject = GetDrawingObject<Update>(new GraphicsDeviceManager());
var myDrawObject = GetDrawingObject<Draw>(null);
}
Granted, you'd only want the create instances via the factory to guarantee you always have an appropriately initialized object. Perhaps using a dependency injection framework like AutoFac would make sense; Update() could "ask" the IoC container for a new GraphicsDeviceManager object.
You could do this with generics trick, but it still is vulnerable to what Jon Skeet wrote:
public interface IHasDefaultConstructor<T> where T : IHasDefaultConstructor<T>, new()
{
}
Class that implements this interface must have parameterless constructor:
public class A : IHasDefaultConstructor<A> //Notice A as generic parameter
{
public A(int a) { } //compile time error
}
The purpose of an interface is to enforce a certain object signature. It should explicitly not be concerned with how an object works internally. Therefore, a constructor in an interface does not really make sense from a conceptual point of view.
There are some alternatives though:
Create an abstract class that acts as a minimal default implementation.
That class should have the constructors you expect implementing classes
to have.
If you don't mind the overkill, use the AbstractFactory pattern and
declare a method in the factory class interface that has the required
signatures.
Pass the GraphicsDeviceManager as a parameter to the Update and Draw methods.
Use a Compositional Object Oriented Programming framework to pass the GraphicsDeviceManager into the part of the object that requires it. This is a pretty experimental solution in my opinion.
The situation you describe is not easy to handle in general. A similar case would be entities in a business application that require access to the database.
you don't.
the constructor is part of the class that can implement an interface. The interface is just a contract of methods the class must implement.
It would be very useful if it were possible to define constructors in interfaces.
Given that an interface is a contract that must be used in the specified way. The following approach might be a viable alternative for some scenarios:
public interface IFoo {
/// <summary>
/// Initialize foo.
/// </summary>
/// <remarks>
/// Classes that implement this interface must invoke this method from
/// each of their constructors.
/// </remarks>
/// <exception cref="InvalidOperationException">
/// Thrown when instance has already been initialized.
/// </exception>
void Initialize(int a);
}
public class ConcreteFoo : IFoo {
private bool _init = false;
public int b;
// Obviously in this case a default value could be used for the
// constructor argument; using overloads for purpose of example
public ConcreteFoo() {
Initialize(42);
}
public ConcreteFoo(int a) {
Initialize(a);
}
public void Initialize(int a) {
if (_init)
throw new InvalidOperationException();
_init = true;
b = a;
}
}
One way to force some sort of constructor is to declare only Getters in interface, which could then mean that the implementing class must have a method, ideally a constructor, to have the value set (privately) for it.
While you can't define a constructor signature in an interface, I feel it's worth mentioning that this may be a spot to consider an abstract class. Abstract classes can define unimplemented (abstract) method signatures in the same way as an interface, but can also have implemented (concrete) methods and constructors.
The downside is that, because it is a type of class, it cannot be used for any of the multiple inheritance type scenarios that an interface can.
I use the following pattern to make it bulletproof.
A developer who derives his class from the base can't accidentally create a public accessible constructor
The final class developer are forced to go through the common create method
Everything is type-safe, no castings are required
It's 100% flexible and can be reused everywhere, where you can define your own base
class.
Try it out you can't break it without making modifications to the base classes (except
if you define an obsolete flag without error flag set to true, but even then you end up with a warning)
public abstract class Base<TSelf, TParameter>
where TSelf : Base<TSelf, TParameter>, new()
{
protected const string FactoryMessage = "Use YourClass.Create(...) instead";
public static TSelf Create(TParameter parameter)
{
var me = new TSelf();
me.Initialize(parameter);
return me;
}
[Obsolete(FactoryMessage, true)]
protected Base()
{
}
protected virtual void Initialize(TParameter parameter)
{
}
}
public abstract class BaseWithConfig<TSelf, TConfig>: Base<TSelf, TConfig>
where TSelf : BaseWithConfig<TSelf, TConfig>, new()
{
public TConfig Config { get; private set; }
[Obsolete(FactoryMessage, true)]
protected BaseWithConfig()
{
}
protected override void Initialize(TConfig parameter)
{
this.Config = parameter;
}
}
public class MyService : BaseWithConfig<MyService, (string UserName, string Password)>
{
[Obsolete(FactoryMessage, true)]
public MyService()
{
}
}
public class Person : Base<Person, (string FirstName, string LastName)>
{
[Obsolete(FactoryMessage,true)]
public Person()
{
}
protected override void Initialize((string FirstName, string LastName) parameter)
{
this.FirstName = parameter.FirstName;
this.LastName = parameter.LastName;
}
public string LastName { get; private set; }
public string FirstName { get; private set; }
}
[Test]
public void FactoryTest()
{
var notInitilaizedPerson = new Person(); // doesn't compile because of the obsolete attribute.
Person max = Person.Create(("Max", "Mustermann"));
Assert.AreEqual("Max",max.FirstName);
var service = MyService.Create(("MyUser", "MyPassword"));
Assert.AreEqual("MyUser", service.Config.UserName);
}
EDIT:
And here is an example based on your drawing example that even enforces interface abstraction
public abstract class BaseWithAbstraction<TSelf, TInterface, TParameter>
where TSelf : BaseWithAbstraction<TSelf, TInterface, TParameter>, TInterface, new()
{
[Obsolete(FactoryMessage, true)]
protected BaseWithAbstraction()
{
}
protected const string FactoryMessage = "Use YourClass.Create(...) instead";
public static TInterface Create(TParameter parameter)
{
var me = new TSelf();
me.Initialize(parameter);
return me;
}
protected virtual void Initialize(TParameter parameter)
{
}
}
public abstract class BaseWithParameter<TSelf, TInterface, TParameter> : BaseWithAbstraction<TSelf, TInterface, TParameter>
where TSelf : BaseWithParameter<TSelf, TInterface, TParameter>, TInterface, new()
{
protected TParameter Parameter { get; private set; }
[Obsolete(FactoryMessage, true)]
protected BaseWithParameter()
{
}
protected sealed override void Initialize(TParameter parameter)
{
this.Parameter = parameter;
this.OnAfterInitialize(parameter);
}
protected virtual void OnAfterInitialize(TParameter parameter)
{
}
}
public class GraphicsDeviceManager
{
}
public interface IDrawable
{
void Update();
void Draw();
}
internal abstract class Drawable<TSelf> : BaseWithParameter<TSelf, IDrawable, GraphicsDeviceManager>, IDrawable
where TSelf : Drawable<TSelf>, IDrawable, new()
{
[Obsolete(FactoryMessage, true)]
protected Drawable()
{
}
public abstract void Update();
public abstract void Draw();
}
internal class Rectangle : Drawable<Rectangle>
{
[Obsolete(FactoryMessage, true)]
public Rectangle()
{
}
public override void Update()
{
GraphicsDeviceManager manager = this.Parameter;
// TODo manager
}
public override void Draw()
{
GraphicsDeviceManager manager = this.Parameter;
// TODo manager
}
}
internal class Circle : Drawable<Circle>
{
[Obsolete(FactoryMessage, true)]
public Circle()
{
}
public override void Update()
{
GraphicsDeviceManager manager = this.Parameter;
// TODo manager
}
public override void Draw()
{
GraphicsDeviceManager manager = this.Parameter;
// TODo manager
}
}
[Test]
public void FactoryTest()
{
// doesn't compile because interface abstraction is enforced.
Rectangle rectangle = Rectangle.Create(new GraphicsDeviceManager());
// you get only the IDrawable returned.
IDrawable service = Circle.Create(new GraphicsDeviceManager());
}

Categories