7

As far as I know, interfaces cannot be instantiated.

If this is true, why does the below code compile and execute? It allows you to create a variable interface. Why is this possible?

Interface:

public interface IDynamicCode<out TCodeOut>
{        
    object DynamicClassInstance { get; set; }
    TCodeOut Execute(string value = "");
}

InCode:

var x = new IDynamicCode<string>[10];

Result:

Result

UPDATE:

It only happens when array declared. Not a single instance.

Hamid Pourjam
  • 20,441
  • 9
  • 58
  • 74
AsValeO
  • 2,859
  • 3
  • 27
  • 64

5 Answers5

17

You're not instantiating an interface, but an array of that interface.

You can assign an instance of any class that implements IDynamicCode<string> to that array. Say you have public class Foo : IDynamicCode<string> { }, you can instantiate that and assign it to an element of that array:

var x = new IDynamicCode<string>[10];
x[5] = new Foo();

Instantiating the interface would not compile:

var bar = new IDynamicCode<string>();
CodeCaster
  • 147,647
  • 23
  • 218
  • 272
13

You're not creating an instance of the interface; you're creating an array which can hold a number of objects which conform to IDynamicCode. Initially, the entries have their default value, which is null.

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
6

this is not creating an interface variable

this will create an array where each element implements the interface. if you write x[0] = new IDynamicCode<string>(); then you will get the error. all of the elements are null, so you need to assign each element an object which implements IDynamicCode

Hamid Pourjam
  • 20,441
  • 9
  • 58
  • 74
5

Just an interesting side-note:

While not possible conceptually, syntactically it is indeed possible to instantiate an interface under specific circumstances.

.NET has something called a CoClassAttribute which tells the compiler to interpret marked interface as specified concrete type. Using this attribute would make the following code perfectly valid and not throw a compile time error (note that this is not an array as in the original post):

var x = new IDynamicCode<string>();

A typical declaration of such attribute would look like this:

[ComImport]
[Guid("68ADA920-3B74-4978-AD6D-29F12A74E3DB")]
[CoClass(typeof(ConcreteDynamicCode<>))]
public interface IDynamicCode<out TCodeOut>
{
    object DynamicClassInstance { get; set; }
    TCodeOut Execute(string value = "");
}

Should this attribute be ever used and if, then where? The answer is "mostly never"! However, there are a couple of scenarios specific to COM interop where this will provide to be a useful feature.

More can be read about the topic from the following links:

Community
  • 1
  • 1
Jaanus Varus
  • 3,508
  • 3
  • 31
  • 49
  • 3
    You're still not instanciating an interface. You're using an interface type in a *new-expression* but are instantiating a proxy object implementing that interface. It's worth noting that this is a case where a *new-expression* will not yield an object of the type specified in the expression. – Laurent LA RIZZA Jun 18 '15 at 13:18
  • That is completely true. Though the syntax of such expression is what can be considered "instantiating an interface" whereas in reality a concrete object is instantiated behind the scene through compiler knowledge of the CoClassAttribute. – Jaanus Varus Jun 18 '15 at 13:23
  • You guys are both saying the same thing, but I prefer @Laurent LA RIZZA's way of stating it. In this scenario you are making it _look_ like you are instantiating an interface, when in fact you are instructing the compiler to use a proxy class as a default replacement type for the interface. Since Java is highly focused on encapsulation, and the _appearance_ of code can be customized independently of its functionality (and this is quite common), I feel it is important to be clear in "weird" cases like this that this is not a hack, and does not violate the rules of the language in any way. – Sam Hazleton Jun 18 '15 at 15:54
3

when you call

var x = new IDynamicCode<string>[10];

Constructors are not called. They are only declared.

fatihk
  • 7,789
  • 1
  • 26
  • 48