36

Developing an interface generic I wished to declare a constructor in an interface but it says constructors are forbidden there. I've tried to declare a static factory method then, but it says neither static methods are allowed and suggests using 'new' keyword. But I have hardly any idea of what could 'new' keyword exactly mean when used inside an interface in C#. Have you?

UPDATE:

I didn't post any sample code because I didn't want to mix 2 questions - how to specify a constructor/factory in an interface AND what does the 'new' keyword mean in interfaces. I I even was only forced to specify the first part because StackOverflow didn't accept the second question in pure form, saying it doesn't meet quality standards.

But, as you demand, I'll sample what I was trying to acheive:

Interface IMyInterface <T, U, V>
{
    IMyInterface (T, U, U);
    // OR
    static IMyInterface GetNewIMyInterface (T, U, U);
}

I just want every derived class to implement such a constructor.

Ivan
  • 63,011
  • 101
  • 250
  • 382
  • 2
    Since interfaces can't be instantiated you can't define a constructor. Could you please post some code. – FIre Panda Jul 05 '11 at 13:08
  • Does this answer your question? [new keyword in method signature](https://stackoverflow.com/questions/1014295/new-keyword-in-method-signature) – Heretic Monkey Mar 30 '22 at 21:21

7 Answers7

80

Bala's answer is correct, but it might be helpful to see why you'd want to do this. Consider the problem that the BCL designers were faced with when designing the libraries for CLR version 2. There was an existing interface:

interface IEnumerable
{
  IEnumerator GetEnumerator();
}

Now you want to add:

interface IEnumerable<T> : IEnumerable
{
  new IEnumerator<T> GetEnumerator();
}

The new interface differs from the old solely in the return type.

What are your choices?

1) Mark the new GetEnumerator as "new" so that the compiler knows that this is intended to be the new method that does not conflict with the old method of the same name but different return type.

2) Change the name to GetEnumerator2.

3) Don't inherit from the original IEnumerable.

Options 2 and 3 are awful. Option 1 is awesome: new enumerables work seamlessly with code that expects old enumerables, but code written to use the new enumerables get the "new" generic behaviour by default.

configurator
  • 40,828
  • 14
  • 81
  • 115
Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • +1 Practical answer. The new implementation acts as an extension to the older implementation. – Karthik Feb 07 '12 at 14:23
  • 1
    +1 Excellent presentation . Just Explained why one would use 'new' keyword in interface inheritance when there is no implementation present. Its because the return might be different and is not included in function signature in C#. Thanks... –  Nov 13 '15 at 04:34
  • In the context of explicit interface declaration you may even want to redefine the member with the exact same signature, as detailed in my answer below. – M Kloster Jul 11 '18 at 12:36
  • I have what I think is another valid use case for using new in an interface. I have a base interface that exposes a property as read-only, with just a getter. But a derived interface that offers a setter as well. So I didn't need to change the return type but I did need to use new on the derived interface to make this happen. Not sure how good or bad the design is but there you have it. – Joe Jun 01 '20 at 15:16
34

The new keyword tells the compiler that your definition hides the definition contained in interfaces your interface might be extending.

Bala R
  • 107,317
  • 23
  • 199
  • 210
  • But interface doesn't have implementation. Suppose Interface1 declares a Method1, and Interface2 inherits from Interface1. If we declare Method1 with the same signature and new keyword inside Interface2 - how would functionality be different from not declaring it inside Interface2 at all? – vkelman Nov 05 '19 at 18:55
  • OK, I saw Eric Lippert's answer below. So, it makes sense to hide a method in descended Interface by re-declaring it with a keyword 'new' **only** if a new method declaration has a different return type. – vkelman Nov 05 '19 at 19:11
  • ... or explicit interface implementation is used – vkelman Nov 05 '19 at 19:22
9

You can't specify either a constructor or a static method in an interface... what you can do is add a type constraint for a generic type parameter, e.g.

void Foo<T>() where T : new()
{
    T t = new T();
    // Do stuff with t
}

Is that what you're thinking of?

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • No. It isn't. I just want every class extending IMyInterface to implement a cousntructor(T, U, U). – Ivan Jul 05 '11 at 13:14
  • 4
    @Ivan: Well you can't do that. There's no way of forcing implementations to have any particular constructors. – Jon Skeet Jul 05 '11 at 13:19
  • Well, you could [Fake Com](http://msmvps.com/blogs/jon_skeet/archive/2009/07/07/faking-com-to-fool-the-c-compiler.aspx) . That will allow you to `new` something that is declared as an `interface`. Obviously this is a totally inappropriate solution to the OP's problem. – Brian Jul 05 '11 at 13:32
  • I saw a piece of code like this method declaration. What does new() accomplish in this context? ToType converter(FromType from) where ToType:new() – C. Tewalt Apr 21 '14 at 16:29
  • 1
    @matrixugly: It requires that the `ToType` type argument has a public parameterless constructor. – Jon Skeet Apr 21 '14 at 16:29
  • Oh cool! Can you require that something has a constructor that takes an int? say 'where ToType: new(int)' I guess this is probably the original question that was asked... – C. Tewalt Apr 21 '14 at 16:33
  • @matrixugly: No, you can't. You can only require a parameterless constructor. – Jon Skeet Apr 21 '14 at 16:38
5

First, the only thing the 'new' keyword actually does is prompt the compiler to NOT produce a warning that you should use the 'new' keyword. Apart from getting rid of the warning, the keyword itself does nothing (in the context in question).

Now, the compiler WANTS you to use the 'new' keyword when you redefine a member (property or method) already defined in an interface you inherit from, and there are at least two possible reasons for doing this. First, as Eric Lippert mentioned above, you may want a method to return a different type (or define a property of the same name with a different type). Another possibility is if you want to define different implementations for the two interfaces:

interface A
{
    void a();
}

interface B : A
{
    new void a();
}

class C : B
{
    void A.a() { Console.WriteLine("Called by interface A!"); }
    void B.a() { Console.WriteLine("Called by interface B!"); }
}

static class Test
{
    public static void DoTest()
    {
        B b = new C();
        b.a();       // Produces "Called by interface B!"
        ((A)b).a();  // Produces "Called by interface A!"
    }
}

If you try to define B.a() in C without redefining a() in B, you get a warning that it is not a member of interface: explicit interface declaration requires that you use an interface for which the member is explicitly defined.

M Kloster
  • 679
  • 4
  • 13
4

An interface is supposed to specify a contract. It will only contain method signatures and no implementation. An interface cannot be instanciated directly, hence a constructor is not allowed in an interface.

http://msdn.microsoft.com/en-us/library/87d83y5b(v=vs.80).aspx

Vincent Mimoun-Prat
  • 28,208
  • 16
  • 81
  • 124
  • I just want a specific constructor signature (with a specific set of parameters) to be a part of the contract, I had no intention to implement it in the constructor. – Ivan Jul 05 '11 at 13:09
  • Then see Jon Skeet answer, I think that is what you need to use in the factory method. – Vincent Mimoun-Prat Jul 05 '11 at 13:12
  • The Interface contract is just saying that the object must support these methods. It does not make sense to define a contructor, because you do not know anything about the make up of the object. If you want to control the object make up more, you need an abstract class to inherit from, but this may not be practical. – Schroedingers Cat Jul 05 '11 at 13:14
4

You're using an interface, but it sounds like you want a base class instead. An interface should never need a constructor, as it can't contain any fields that would need to be initialized in the constructor. I think you want to use a base class instead.

Coeffect
  • 8,772
  • 2
  • 27
  • 42
0

C# and .NET does not allow you to declare a constructor on an interface.

It's simply got to be a stated constraint of implementing that interface (see ISerializable in the .NET libraries).

If you think about it, having a constructor on an interface doesn't make sense, as you have to know the concrete class you want to create when you call the constructor. How would you go about calling such an interface constructor, and what would the result be?

thecoop
  • 45,220
  • 19
  • 132
  • 189
  • It would be useful, as syntactic sugar, to allow an interface (e.g. IFoo) to specify a class with which it would be paired (e.g. StaticFoo); this class could not have any instance fields or virtual methods, but could have constructors and instance methods or properties. An attempt to use a member not present in the interface would use one from the class (similar to extension methods, but with clearer scoping rules, and with the ability to extend properties as well as methods). An attempt to use a constructor on the interface would be equivalent to calling the one for the paired class. – supercat Jul 06 '11 at 19:53
  • Functionally, it would basically be syntactic sugar, but it would make for cleaner code in cases where an interface method would have several overloads, one of which is called by the others using default parameters. Also, IMHO, saying "IEnumerable.Empty" seems cleaner than "Enumerable.Empty". – supercat Jul 06 '11 at 19:56