Problem
It’s strange that this is the first time I’ve seen this issue, but:
In a C# interface, how do you define a constructor?
Edit: Some people asked for an example (yes, it’s a game; it’s a free time project).
IDrawable +Update +Draw
It will always require a GraphicsDeviceManager to update (check for edge of screen, etc.) and draw itself. As a result, I’d like to ensure that the object has a reference to it. This is something that belongs in the constructor.
Now that I’ve written it down, I believe I’m using IObservable, and the GraphicsDeviceManager should use IDrawable… Either I don’t understand the XNA framework or the framework is poorly designed.
Edit: It appears that my definition of constructor in the context of an interface has caused some confusion. Because an interface cannot be instantiated, it does not require 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.
Asked by Boris Callens
Solution #1
You can’t do it. It can be a pain at times, but you wouldn’t be able to call it that using traditional methods.
In a blog article, I proposed static interfaces, which would only be used in general type restrictions but, in my opinion, may be quite useful.
One point regarding how you’d have problems deriving classes if you could define a constructor within an interface:
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)
{
}
}
Answered by Jon Skeet
Solution #2
Constructors are not allowed on Interfaces, as previously stated. But, given this is still a top Google result 7 years later, I thought I’d add my two cents – especially, to explain how you could utilise an abstract base class in conjunction with your existing Interface to reduce the amount of refactoring required in similar scenarios in the future. This topic has previously been mentioned in a few comments, but I thought it was worth demonstrating how to achieve it.
So far, this is what your main interface looks like:
public interface IDrawable
{
void Update();
void Draw();
}
Create an abstract class that contains the constructor you want to enforce. Actually, since it’s been available since you asked your initial question, we can get a bit fancy here and utilize generics to adapt this to other interfaces that may require the same functionality but have different constructor requirements:
public abstract class MustInitialize<T>
{
public MustInitialize(T parameters)
{
}
}
You must now construct a new class that inherits from the IDrawable interface as well as 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 simply construct a Drawable instance and you’re ready to go:
IDrawable drawableService = new Drawable(myGraphicsDeviceManager);
The wonderful part about this is that the new Drawable class we developed still behaves just like 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.
Answered by Dan
Solution #3
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 the type name replaces the implementation of the “interface function Object() { [native code] }” by convention.
Now consider the following scenario:
ICustomer a = new Person("Ernie");
Would we claim that ICustomer’s contract is being followed?
And what about this:
interface ICustomer
{
ICustomer(string address);
}
Answered by Gert Arnold
Solution #4
You can’t.
Interfaces define obligations that other objects must follow, therefore they don’t require any initialization.
Instead of utilizing an abstract base class, you should use an abstract base class if you have some state that needs to be initialized.
Answered by Michael
Solution #5
Looking back at the question, I thought to myself, “Perhaps we’re approaching this problem incorrectly.” When it comes to defining a constructor with specific parameters, interfaces may not be the best option… but a (abstract) base class is.
If you create a base class with a constructor that accepts the parameters you require, every class that derives from it must provide them as well.
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
{
}
}
Answered by Jeroen Landheer
Post is based on https://stackoverflow.com/questions/619856/interface-defining-a-constructor-signature