629

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.

Adi Lester
  • 24,731
  • 12
  • 95
  • 110
Boris Callens
  • 90,659
  • 85
  • 207
  • 305
  • 3
    Instead of having an interface defining your constructor, have an interface defining your factory methods instead. – Doctor Jones Dec 04 '17 at 12:17

16 Answers16

341

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)
    {
    }
}
kevinarpe
  • 20,319
  • 26
  • 127
  • 154
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 5
    I could see problems indeed, but the same goes for all other methods you define. Usually NotSupportedException is the only way out. – Boris Callens Mar 06 '09 at 18:25
  • 7
    @boris: The difference is that there's always *something* to be called with normal inheritance, guaranteed by the compiler. In this case there's something which "ought" to be there but isn't. – Jon Skeet Mar 06 '09 at 19:01
  • 1
    If type A inherits from type B which in its turn implements interface I, doesn't A provide I's props and methods? From your previous sentence I deduct not, but I can't come up with an anti-example. – Boris Callens Mar 06 '09 at 19:59
  • @boris: Yes, but that can't apply to constructors - because you'd want the constructor to create a Bar rather than a Foo, and there's no suitable Bar constructor. That's the problem :) – Jon Skeet Mar 06 '09 at 20:03
  • 81
    Yeah but what's wrong with that, there's no suitable Bar constructor because it doesn't satisfy the interface properly. That'd be like saying you can't define methods in interfaces because if you don't implement it, it won't work. – jsimmons Aug 08 '10 at 06:21
  • 5
    @jsimmons: No, you've missed my point. With normal interfaces, any type deriving from a type which implements an interface automatically implements the interface too. That wouldn't be the case here. – Jon Skeet Aug 08 '10 at 07:00
  • 3
    Ah I see, but would that be such an issue? It'd just mean as part of the inheritance, you'd be required to implement a certain constructor. I mean, after all construction is part of the public API that an interface is want to define. Unless it implies some larger issue in the compiler? – jsimmons Aug 09 '10 at 00:59
  • 2
    @jsimmons: Well it means a type can't implement a new interface after the first release, as it would then potentially break existing subtypes. These aren't insurmountable, but they're extra things to think about - problems that don't currently exist. – Jon Skeet Aug 09 '10 at 05:20
  • How about allowing an interface to declare a static factory method which will be used if someone calls "new" on the interface type? Would that cause any problems? – supercat Jul 23 '11 at 02:53
  • I don't care what the limitations are, but it would be very useful to allow the interface to specify a constructor with certain parameters. What if we want to guarantee that the class is immutable, which means passing in certain key parameters via the constructor? – Contango Oct 05 '11 at 09:14
  • 10
    @Gravitas: Useful or not, it's certainly not available today. I suspect if this feature were ever to show up, it would require rather more careful design than we can do in comments :) – Jon Skeet Oct 05 '11 at 09:29
  • As per your blog entry; implementing classes could require they be `sealed` to implement an interface with a constructor. Of course, this would kill the possibility of inheritance, but using these interfaces like markers to concrete classes seems logical to me anyways. – Dan Lugg Nov 09 '12 at 19:22
  • 1
    As a work around, I find myself with lots of `where T:ISomeInterface,new()` sprinkled everywhere. The purpose of this is to allow some generic algorithm to create new instances of ISomeInterface without knowing the concrete type, while the user of the algorithm is required to provide a default constructor in their implementation of ISomeInterface. – AaronLS Dec 14 '12 at 00:18
  • I fail to see the issue here. The purpose of the Interface is to provide a contract between the class that impliments the Interface and the class/method/whatever the object of that Interface, such that the object abiding by the contract can be refered to by the interface type, as opposed to the actual class type. Since the Interface doesn't care how the object is created, just that the object has certain properties/methods, it would make no difference what is put in the constructor, and therefore it would make no sense to include constructor definitions in the Interface itself. It seems... – William Jan 08 '13 at 19:24
  • ...That constructor definition would be more in light with implimentation, and not as much part of the Interface itself. – William Jan 08 '13 at 19:26
  • 11
    @user1721649: There are plenty of places where I've wanted this - almost always with generic constraints. Basically, you want to be able to call a constructor within a generic method, to create an instance of the generic type implementing some interface. It really *would* be useful. – Jon Skeet Jan 08 '13 at 19:45
  • @Shimmy: I'm not sure what you're looking for from me... while my static interfaces idea is interesting (to me, anyway) I'm afraid it doesn't have any basis in reality yet :( – Jon Skeet May 12 '13 at 17:29
  • @Jon, Regarding the static interfaces. I'm working on an API proj. that has a chain of classes in a hierarchy that all of them have a `Read(BinaryStream s)` static method instantiating current type. I could obviously create an abstract base class that defines a T static method where T is current type, problem is some of these classes inherit from `Collection`, and I'm doubting whether I should invert them all to `ICollection`, embodying the collection in the classes, themselves. What choice would you pick? I don't mind the time cost, I just want it to be designed better for the future. – Shimmy Weitzhandler May 12 '13 at 17:33
  • I actually committed prev. comment by mistake, I was still editing it and prob. pressed enter by accidentally. Read my updated one above. Thanks for your time Jon. – Shimmy Weitzhandler May 12 '13 at 17:34
  • @Shimmy: I'm not sure what you mean by "invert them" here. But yes, I'd probably declare each method to return `ICollection` rather than `Collection`. – Jon Skeet May 12 '13 at 17:38
  • I was saying that some of those classes in the downline, are subclasses of `Collection` and besides that have a static method as above. Question is whether I should live it as it is, or make the Collection as a property, to allow inheriting from `BinaryReadableBase` that has a generic function `Read(BinaryReader r)`. – Shimmy Weitzhandler May 12 '13 at 17:42
  • @JonSkeet, oops, I forgot that static methods cannot be overriden/implemented on abstract classes either... – Shimmy Weitzhandler May 12 '13 at 18:10
  • I wonder if there might be a solution/feature a compiler could support that would achieve the goal of being able to treat different classes the same in regard to construction, but maybe not through interfaces. Because I think the goal here isn't bad... but we just default to thinking it would have to be done through an interface which is clearly not a good choice. – BVernon Jan 29 '15 at 04:51
  • @William The issue is how you interpret "can be refered to". If you think of an interface as just an enforcement of 'methods', then sure. But consider an init method declared as part of the interface. Now...what is the purpose of an init method? What is the purpose of a constructor? You can declare an init method in an interface...but not a constructor?!? I (would like to) interpret a constructor the same way as I interpret any other method declared in an interface, which is: "I want to be able to *communicate* with this object using such and such interface"... – Ash Aug 25 '17 at 06:53
  • @William ... But unfortunately, while I can *communicate* and tell the object what it needs to do, I can't tell it how to construct itself. – Ash Aug 25 '17 at 06:53
  • @Ash Init would usually be a factory method that would initiate variables within the class, but it still isn't instantiating the class. – William Oct 21 '17 at 17:59
  • 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 { } } –  Aug 04 '21 at 08:30
  • Huzzah. It's 2022 and we're getting static interface properties https://www.youtube.com/watch?v=KKo0qJUlXGI – Boris Callens Jun 14 '22 at 09:22
202

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.

Dan
  • 3,583
  • 1
  • 23
  • 18
  • 22
    It is important to emphasize that you can't create a "MustInitialize" class to cover every case, because C# does not allow multiple inheritance. Meaning that if your class inherits an abstract class cannot inherits another class too. – Skarllot Apr 22 '17 at 01:08
  • 4
    That is true @Skarlot, it's not a silver bullet solution. In the problem you point out though, hopefully it would make sense to directly modify the abstract class that you are already inheriting. But there are still situations where that isn't possible and/or appropriate, so a deeper design pattern would be required. – Dan Apr 24 '17 at 00:04
  • 1
    In C# you can only inheret from one base class, so inhereting from MustInitialize prevents you from inhereting from other classes. An alternative would be to have a method that acts like a constuctor - setting the classes properties and fields, maybe with sentinels that prevent it being called twice successfully, or the class to be used until that method is called. – andrew pate Jun 14 '17 at 10:04
  • 2
    @andrew pate - As Skarllot has pointed out, that is true about multiple inheritance, but it is not a concern in this specific case from the OP. Although what you proposed would work, I wouldn't recommend ever writing a class that requires a public method to be called in order to be used properly. If you're not familiar with the term, google "Temporal Coupling". – Dan Jun 14 '17 at 12:48
  • @Dan, good point about temporal coupling. A hack could be to put in a sutably named reminder method, which is not expected to contain an implementation for example: ExpectedConstructorSignature_Drawable(GraphicsDeviceManager graphicsDeviceManager) – andrew pate Jun 14 '17 at 13:16
151

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);
}
Ajay
  • 18,086
  • 12
  • 59
  • 105
Gert Arnold
  • 105,341
  • 31
  • 202
  • 291
  • 22
    if you have a method by the same signature and name in ICustomer and IPerson, this problem is there also. I do not see how this helps. Interfaces are not for "only my definition". It is for "include me at any cost" – nawfal Oct 09 '12 at 06:08
  • 7
    @nawfal The point is that an interface never demands that a method is _executed_, only that it should exist. It can never guarantee state. Contrary, a "constructor interface" does demand that something be done (executed) when an object is constructed. This can never be guaranteed when there are different interfaces. – Gert Arnold Oct 09 '12 at 06:59
  • 9
    @GertArnold a method does its job, while a constructor does its. I do not know understand what is the difference here. Interfaces make a contract that "my implementation should be there", not like "mine should be the only implementation". I would say for consistency, this should be valid for constructors, methods, properties – nawfal Oct 09 '12 at 07:44
  • @nawfal Strictly speaking you are right, but the discussion here (and in similar points) is about requiring an object to have a certain state when it is initialized ("I want to make sure the object has a reference to `GraphicsDeviceManager`"). Constructor interfaces cannot do that. – Gert Arnold Oct 09 '12 at 08:22
  • 10
    I don't see how this is a problem, one could simply make a rule that only allows chaining interfaces with identical constructor signatures. It would be the same behavior as if interface A implements "foo : int" and interface B implements "foo : string", they are just not compatible. – Toodleey Apr 12 '13 at 10:34
  • @Toodleey Sure, that could be a rule. Maybe a syntax like `new (IBar)Foo("x")` could be introduced to enforce the use of an interface, a bit like an explicit implementation. – Gert Arnold Apr 12 '13 at 17:22
  • 3
    It reminds me of c++ multiple inheritence problem without virtual inheritance – prabhakaran Mar 04 '14 at 05:47
  • 2
    +1, while rather vague this is probably the best explanation why interfaces, not only in C# but in many languages (such as Java), can't have constructor members. – Qix - MONICA WAS MISTREATED Nov 17 '14 at 23:32
  • Well, ICustomer(string address) collides with the signature ICustomer(string name) But wouldn't the first part of the answer be potentially addressable by the use of "this(z, 12, x)" e.g. public MyCustomer(string name) must also include : this(DateTime.Today) and MyCustomer(string name, DateTime registered) : this(name), this(registered) [not that the multiple "This" calls are allowed ATM] – Roger Willcocks Oct 11 '16 at 02:59
  • when I add constractor to inteface I get this error: "Interfaces cannot contain constructors" – rikush Oct 04 '18 at 12:37
  • @rikush Yeah, that's why I say "Suppose we *could* have". – Gert Arnold Oct 04 '18 at 12:41
67

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.

Michael
  • 54,279
  • 5
  • 125
  • 144
  • 13
    Why cant a contract have a state? – Sandeep Datta Sep 21 '11 at 12:40
  • 15
    Because the contract binds you to provide a certain _behaviour_. How interfaces are used implies extracting common behaviours, and that is not dependent on state (which would then be an implementation detail). – Cornelius Nov 15 '12 at 13:58
  • 1
    Seems we could use a separate mechanic like a "contract" apart from interfaces for requiring an object to implement certain features like constructors and static methods/properties that will not be called through the contract (like you would if it were an interface). Feature suggestion for next .Net version? – Vincent Vancalbergh Oct 24 '14 at 15:02
21

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
  {
  }
}
Jeroen Landheer
  • 9,160
  • 2
  • 36
  • 43
  • This is how I solved this issue as well. My interface defines what the class needs to be able to do, but my base abstract class enforces the constructor component of it. – Bill Sambrone May 14 '14 at 20:45
20

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.

Jeroen Landheer
  • 9,160
  • 2
  • 36
  • 43
  • 1
    I would use the interface constructor to make sure some arguments are defenatly set (through the constructor) so a parameterless ctor is not really what I'm looking for. – Boris Callens Mar 06 '09 at 18:44
8

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.

Cesar
  • 2,059
  • 25
  • 30
7

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

JTtheGeek
  • 1,707
  • 14
  • 17
5

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.

Matthew
  • 706
  • 9
  • 12
  • It looks like you can leave the constraints on the interface, but there is no way for the compiler to know that the factory is going to return something the implements it, so just implicitly implement IDrawableFactory `public TDrawable GetDrawingObject(GraphicsDeviceManager graphicsDeviceManager)` – Matthew Jun 28 '12 at 21:30
  • Hahah I wrote my response before noticing yours Matt, looks like we think alike but I think you should use the generic on the interface itself with the where clause to lock the type – JTtheGeek Jun 29 '12 at 03:49
  • @JTtheGeek - I think I understand partially, but it seems to me it would make my factory too rigid, more like overriding an abstract base class. I would have to instantiate a completely new factory object to get at the underlying types, right? This is why I only put the constraints on the builder method, but I may be missing the mark. Perhaps you could post an example of what you'd change to help me see it more clearly. Needing to pass null to create a Draw object to satisfy the parameter requirements even though Draw may have an empty, default ctor is definitely a drawback to my approach. – Matthew Jun 29 '12 at 15:11
3

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
}
ghord
  • 13,260
  • 6
  • 44
  • 69
  • 1
    A few caveats: 1. The restriction comes from `new()`, checking for the own interface of rather limited use / overkill. 2. As soon as you declare constructors, the compiler stops auto-generating a parameterless constructor. Some readers may not catch on to that from your code-example. 3. Checking classes / instances for generic interfaces is inconvenient. 4. What Jon Skeet said – Lorenz Lo Sauer Aug 27 '16 at 05:04
2

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.

MauganRa
  • 494
  • 6
  • 8
  • 1
    I'm not sure I understand the 'therefore'. The implementation of a constructor (what it does) is internal, but how is a constructor itself internal? How is it any more or less 'internal' than a method? It's certainly called externally when creating an instance... – Joe May 22 '18 at 16:09
  • @Joe It is a design decision made by Java. It would be conceivable to create a language that offers mandatory constructors. However, it would make dependency injection via constructor injection impossible. Also, object creation by constructor is a very technical concern that not always translate cleanly to business logic. For example, for a class `BlogPost`, object creation (possibily after loading its data from the database) and actual blog post creation are two different events. – MauganRa May 23 '18 at 22:17
0

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;
    }

}
Lea Hayes
  • 62,536
  • 16
  • 62
  • 111
0

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.

Kunal
  • 75
  • 1
  • 2
  • 10
0

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.

0

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());
    }
Tom
  • 41
  • 5
0

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.

royatl
  • 336
  • 1
  • 7