Related
Say I have a generic class Foo, that has a variable that is protected
public class Foo<T>
{
protected bool knowsFu;
}
I also have 2 sub-classes: Bar and Pipe
public class Bar : Foo<Bar> {}
public class Pipe : Foo<Pipe> {}
It is actually possible for me to access the knowsFu in Pipe FROM Bar, e.g.:
public class Bar : Foo<Bar>
{
void UpdateFuInOtherClass(Pipe p)
{
p.knowsFu = false;
}
}
Is this intended behaviour? (If so, what would be the usecase?)
Is there a way for me to prevent other Foo-Subclasses from modifying/reaching the protected variable inside of my current subclass?
More specifically: I'm using a generic class to implement the Singleton-Pattern:
https://en.wikipedia.org/wiki/Singleton_pattern
However, I'm currently able to access any singleton's protected instance-variable, as long as I am inside of another Singleton. Is there a way to prevent this?
EDIT: It might be relevant to note that the protected variable (knowsFu) is actually STATIC as well.
EDIT2: Ok, maybe the example was abit too generic.. here's how I'm actually currently implementing it:
why use Singleton? A:The platform I'm working on is Unity3D, in which the pattern is used frequently
I have a generically typed abstract class SingletonBehaviour
public abstract class SingletonBehaviour<T> where T : MonoBehaviour
{
public static T Instance { get { return instance; } }
protected static T instance { get; private set; } }
// Loading is done through Unitys Awake-Method
}
One of the Singleton-Objects that I'm using is the APIManager
public class APIManager : SingletonBehaviour<APIManager>
{
// Methods like SendHTTPPost(), HTTPGet(), etc.
}
However, since most of my projects need some better API-implementation than that, what I'm currently doing is:
public class ProjectAAPIManager : APIManager
{
// Overriding Instance so my return value is not APIManager but instead ProjectAAPIManager
public static new ProjectAAPIMamager Instance { get { return (ProjectAAPIManager)instance; } }
}
This ^ is the reason my (inner) instance-variable is protected, and not private.
However, because of this, any other SingletonBehaviour in my project can now access the (inner) instance-variable on my ProjectAAPIManager
public class GameController : SingletonBehaviour<GameController>
{
private void AMethod()
{
// Accessing inner variable instead of public one
ProjectAAPIManager.instance.DoSomething();
}
}
As it's only the getter, this currently does not really matter. But what if I'd need access to the setter in my subclass as well?
Also: would it be worth it to generically type my APIManager as well?
Your question is nothing short of bewildering. How can you make a protected member not be accesible from a derived class? Well, a good start is not making it protected.
protected is by definition exactly what you don't want, so don't use it! Use private instead.
If what you are asking is how to make it a readonly member when accessed from derived types, you have two options:
Declare it as readonly in the base class if possible.
Use a protected property instead with a private setter.
Many novice coders seems to think protected members aren't part of the public surface of the type but they really are, as long as the class can be extended. As such, the rules of public members apply: never expose public fields unless they are readonly or constants, use properties instead.
You should not have classes that implement your generic singleton class.
Otherwise, by default, your protected fields will be accessible by the subclasses (it's what "protected" keyword does)
Instead, you should do something like this:
class Program
{
static void Main(string[] args)
{
var barInstance = Foo<Bar>.GetInstance();
}
}
public class Foo<T> where T : new()
{
protected bool knowsFu;
private static T _instance;
public static T GetInstance()
{
if (_instance == null)
_instance = new T();
return _instance;
}
}
public class Bar
{
public Bar()
{
}
}
Edit 1:
To use a singleton, you should not make another class implement the singleton behavior (This is not how the singleton pattern works).
To use the same classes as your second example, you should do something like this.
public class SingletonBehaviour<T> where T : new()
{
public static T Instance
{
get
{
if(instance == null)
instance = new T()
return instance;
}
}
private static T instance { get; set; }
}
public class APIManager // This class should not inherit from the SingletonBehavior class
{
// Methods like SendHTTPPost(), HTTPGet(), etc.
}
public class ProjectAAPIManager : APIManager
{
public ProjectAAPIManager GetInstance() => SingletonBehavior<ProjectAAPIManager>.Instance();
}
I have a base class which has a nested type, inside. There's a function in the outer (base) type which would be overridden by it's children later. In fact this function belongs to the inner type from the OO prespective but still I need it, to be overridden by subtypes of the base class.
Should I use this function as a callback from the inner type or just move it inside the inner type and let's the subtypes to override it from there?
EDIT: Sample code added
class A
{
protected void func() { /* do something */ }
class B { /**/ }
}
// OR
class A
{
class B
{
protected void func() { /* do something */ }
}
}
// Then
class C : A
{
override func() { /**/ }
}
My suggestion is to crate a delegate for the inner type function which is initiated by the constructor of the base class:
internal class BaseClass
{
public BaseClass(Action myAction)
{
this.innerType = new InnerType(myAction);
}
public BaseClass()
{
// When no function delegate is supplied, InnerType should default to
// using its own implementation of the specific function
this.innerType = new InnerType();
}
}
As you see, deriving types can call the base constructor with :base (overridenAction) where they can provide their own implementation of the function right to the innermost type. Of course, you are not obligated to use Action but any delegate you want.
IMO what you are describing looks like The Strategy design pattern. Consider using this pattern. Your code would be much more maintainable as it contains well recognizable pattern. You also can take a look at state design pattern, usually you have to choose between these two, they are closely connected.
In this scenario:
class A
{
class B
{
protected void func() { // do something }
}
}
You cannot derive from class A and override func() in class B.
From your description it seems that A-derived classes should be able to override some function (or functionality) in the inner class B which indicates that you maybe should rethink your design. Either extract B and don't make it an inner class or make the functionality you want to override an explicit dependency via an interface like this:
class A
{
private B _MyB;
public A(ISomeBehaviour behaviour)
{
_MyB = new B(behaviour);
}
}
In anyway if you want to stick with your design then I would not recommend the delegate approach and rather choose the override because with the delegates it makes it harder to add decoration if that is all you need in your child classes.
This is how the outer class can serve as a strategy to the inner service class.
Note that using pattern names such as TemplateMethod and Strategy as real class names is not recommended, use whatever is meaningful in the domain. Same applies to Outer and Inner.
public class Consumer
{
public void Foo()
{
IOuterFoo fooService = new Derived();
fooService.OuterFoo();
}
}
// ...
public interface IOuterFoo
{
void OuterFoo();
}
abstract class Base : Base.IStrategy, IOuterFoo
{
public void OuterFoo() { _service.Foo(); }
private readonly InnerService _service;
protected Base() { _service = new InnerService(this); }
private interface IStrategy { void Foo(); }
private class InnerService
{
private readonly IStrategy _strategy;
public InnerService(IStrategy strategy) { _strategy = strategy; }
public void Foo() { _strategy.Foo(); }
}
void IStrategy.Foo() { TemplateMethodFoo(); }
protected abstract void TemplateMethodFoo();
}
class Derived : Base
{
protected override void TemplateMethodFoo()
{
throw new NotImplementedException();
}
}
So, I'd like to hear what you all think about this.
I have a project where three different inheritance paths need to all implement another base class. This would be multiple inheritance and isn't allowed in C#. I am curious how I can implement this without code duplication.
EDIT: I don't own the three classes. The three classes are from 3rd party code. So I cannot make them all extend my base class.
Right now I am using three different classes, each one extending a different base class. Then I have the same code in each of the three abstract classes.
I could use a single interface, but I would still need to duplicate the code.
I could make some kind of static class that implements the code and then reference that in each of the 3 abstract classes. It would eliminate the duplication, but, I am not sure how I feel about this. I could implement Extensions methods on the interface, but then the interface itself would be empty and the extension methods (containing the duplicate code) would be in a totally different file, which seems not quite right. Plus I can't implement properties in extension methods...
How can I factor out the code duplication here?
EDIT, inheritance tree:
class Class1 : 3rdPartyBaseClass1 { }
class Class2 : 3rdPartyBaseClass2 { }
class Class3 : 3rdPartyBaseClass3 { }
I have code I want to be in each of the above Classes, but I cannot add it to the 3rdPartyClasses.
Create an interface that Class1, Class2, and Class3 can implement. Then put your code in extension methods so it will apply to all.
interface IMyInterface {
void Foo(); //these are the methods that these
//classes actually have in common
void Bar();
}
public class Class1 : 3rdPartyBaseClass1, IMyInterface {
// whatever
}
public static class IMyInterfaceExtensions {
public static void CommonMethod(this IMyInterface obj) {
obj.Foo();
obj.Bar();
}
}
public static class Program {
public static void Main() {
var instance = new Class1();
instance.CommonMethod();
}
}
OK, you can do something similar to my previous suggestion, and also similar to recursive's suggestion. For the functionality you require in all three of your derived classes, you can create a single Interface along with a single class (call it "Implementer" for kicks) that implements that Interface (and that has the actual code you want executed with each call).
In each of your derived classes, then, you implement the Interface and create a private instance of Implementer. In each of the interface methods, you just pass the call along to the private instance of Implementer. Because Implementer and your derived classes all implement your Interface, any changes you make to the Interface will require you to modify Implementer and the derived classes accordingly.
And all your code is in one place, except for all the lines passings the calls on to the private instance of Implementer (obviously multiple inheritance would be better than this, but you go to war with the army you have, not the army you wish you had).
Update: what about just adding a public instance of your class to each of the derived classes?
public class DerivedClass1 : ThirdPartyClass1
{
public MyClass myClass = new MyClass();
}
Or if you care who Demeter is and you get paid by LOC:
public class DerivedClass1 : ThirdPartyClass1
{
private MyClass _myClass = new MyClass();
public MyClass myClass
{
get
{
return _myClass;
}
}
}
Then you'd just call the MyClass methods like this:
DerivedClass1 dc1 = new DerivedClass1();
dc1.myClass.DoSomething();
This way, we could all go to sleep.
Similar to MusiGenesis's suggestion, if you need the functionality of the 3rd party classes but do not have to descend from them, you could use composition as follows:
class ThirdPartyBaseClass1
{
public void DoOne() {}
}
class ThirdPartyBaseClass2
{
public void DoTwo() { }
}
class ThirdPartyBaseClass3
{
public void DoThree() { }
}
abstract class Base
{
public void DoAll() { }
}
class Class1 : Base
{
public void DoOne() { _doer.DoOne(); }
private readonly ThirdPartyBaseClass1 _doer = new ThirdPartyBaseClass1();
}
class Class2 : Base
{
public void DoTwo() { _doer.DoTwo(); }
private readonly ThirdPartyBaseClass2 _doer = new ThirdPartyBaseClass2();
}
class Class3 : Base
{
public void DoThree() { _doer.DoThree(); }
private readonly ThirdPartyBaseClass3 _doer = new ThirdPartyBaseClass3();
}
This also gives you the freedom to define whatever interfaces you want and implement them on your classes.
Sounds like you need to insert the new abstract class into the inheritance tree at whatever point those three paths come together, but there really isn't enough information to tell. If you could post some of your inheritance tree, that would help a lot.
I think you may want to use composition instead of inheritance. Exactly how to do this depends on what the third party classes look like, and what your own code looks like. Some more specific code relating to your problem would be helpful, but for example, suppose you want to have three different third party GUI widgets that all need to be customized with your own initializer code.
Case 1: Suppose your third party widgets look like:
public interface IThirdPartyWidget {
public void doWidgetStuff();
}
public class ThirdPartyWidget1: ThirdyPartyWidget implements IThirdPartyWidget {
...
}
public class ThirdPartyWidget2: ThirdPartyWidget implements IThirdPartyWidget {
...
}
You can do:
public class MyWidget implements IThirdPartyWidget {
private IThirdPartyWidget delegateWidget;
public MyWidget(IThirdPartyWidget delegateWidget) {
this.delegateWidget = delegateWidget;
}
public void doWidgetStuff() {
delegateWidget.doWidgetStuff();
}
}
Case 2: Suppose you absolutely need to extend those widgets, and you have to refactor your own code:
public class MyWidget1: ThirdPartyWidget1 {
public void myMethod() {
runMyCode();
}
private void runMyCode() {
//something complicated happens
}
}
public class MyWidget2: ThirdPartyWidget2 {
public void myMethod() {
runMyCode();
}
private void runMyCode() {
//something complicated happens
}
}
This can become:
public class MyCodeRunner {
public void runMyCode() {
//...
}
}
public class MyWidget1: ThirdPartyWidget1 {
private MyCodeRunner myCode = new MyCodeRunner();
public void myMethod() {
myCode .runMyCode();
}
}
public class MyWidget2: ThirdPartyWidget2 {
private MyCodeRunner myCode = new MyCodeRunner();
public void myMethod() {
myCode .runMyCode();
}
}
Hope this makes sense!
The base class user should access the original method
class A
public init()
The derived class user should aceess ONLY the derived method.
class B
public init(int info)
I cannot use "override" bc there's a different signature.
What options do I have so that the derived class user does not see two methods.
Notes.
All in all I just need two classes that share some code. Inheritance is not a must.
But simplicity for the user of B is a priority.
This is a big code smell (and violates some basic OOP tenets) and, to the best of my knowledge, can not be done in any language. In OOP, an instance of B is an instance of A; this is polymorphism. So if A has a public method named init accepting no parameters, then so does B.
What are you trying to do this for?
Edit: Now that you've added the edit that states that inheritance is not a must, just use composition to share code. Give B a private instance of A, for example.
According to the Liskov principle you simply cannot do that, because it would violate this principle. The best thing you can to is override init() in the derived class and make it throw an exception every time it's invoked, stating that the user should use init(int info) and rely on the test to catch the errors.
Why you can't simple replace the init() method or even make it protected?
The Liskov principle states (rephrased) that where an instance of class A is required, an isntance of class B extends A can be passed.
If a method expects A and wants to call init() on it and you pass B (which extends A) to it with a protected init() the method will fail. This is the reason why the code will not even compile.
What you're asking for is impossible, due to the nature of the type system. Any instance of B can be thought of as an A, so you can call any of A's methods (including Init()). The best you can do is overload Init() in B and throw an exception to catch this at runtime.
public class B
{
void Init()
{
throw new NotSupportedException();
}
}
Contrary to some answers/comments here, what you are asking for would have a real use if it existed:
class Derived : Base
{
This can be seen by considering the workaround:
class Derived
{
private Base _base = new Base();
In other words, it's not really a base class at all, but a hidden part of the implementation.
The downside with this workaround is: what Base has an abstract method that you have to supply? You have to write this:
class Derived
{
class ActualDerived : Base
{
// override abstract method(s)
}
private Base _base = new ActualDerived();
This is the whole point of private inheritance (as found in C++) - it's for situations when you want to inherit the implementation but not the "interface" (in the informal sense).
But in C#, it's not available.
Presumabely A and B have something in common. Can you factor that out into a different base class?
public class Base
{
... common stuff ...
}
public class A : Base
{
public void Init()
{
}
}
public class B : Base
{
public void Init(int info)
{
}
}
if you need polymorphism then references to Base or, better yet, Thomas' interface are the way to go.
Instead of inheritance, use an interface as a "middle man":
public interface IAllThatYouNeed
{
public void DoSomeStuff();
}
public class A : IAllThatYouNeed
{
public void Init() {
// do stuff
}
}
public class B : IAllThatYouNeed
{
public void Init(int info) {
// do stuff
}
}
it looks like it's not yet possible
i tried to do something like this:
public class B : A
{
private override void Init() { }
public void Init(int x)
{ }
}
but Init() it's still visible from the A class
There is no perfect solution here. Some possible ways to do it:
An approach would be to make A.Init() virtual, override it in B and make it throw a NotImplementedException/InvalidOperationException.
Init() stays visible, but the user finds out very quickly that it is not to be used (make it explicit that Init(int info) is to be used in the XML documentation and in the message of the exception).
If you don't care about the inheritance part and just want to use the functionalities of class A in class B, don't have B deriving from A and make B instantiate A and use its functionalities.
Edit:
You can use an interface implementing the common operations in order to retain inheritance while avoiding to implement Init() in B:
public interface IOperations
{
void DoStuff();
void Foo();
}
public class A : IOperations
{
public void Init()
{
// Do class A init stuff
}
#region IOperations Members
public void DoStuff()
{
// ...
}
public void Foo()
{
// ...
}
#endregion
}
public class B : IOperations
{
A _operations = new A();
public void Init(int initData)
{
_operations.Init();
// Do class B init stuff
}
#region IOperations Members
public void DoStuff()
{
_operations.DoStuff();
}
public void Foo()
{
_operations.Foo();
}
#endregion
}
This can be made even better by using a factory:
public static class OperationsFactory
{
public static IOperations CreateOperations()
{
A result = new A();
result.Init();
return result;
}
public static IOperations CreateOperations(int initData)
{
B result = new B();
result.Init(initData);
return result;
}
}
This way instantiation code is well encapsulated, the difference between the two Init() methods is hidden from the user code.
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());
}