为什么接口变量实例化是可能的?

Why is interface variable instantiation possible?

据我所知,接口不能被实例化。

如果是这样,为什么下面的代码可以编译执行?它允许您创建可变接口。为什么这是可能的?

接口:

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

InCode:

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

结果:

更新:

只有声明数组时才会发生。没有一个例子。

您不是在实例化接口,而是在实例化该接口的数组。

您可以将实现 IDynamicCode<string> 的任何 class 的实例分配给该数组。假设您有 public class Foo : IDynamicCode<string> { },您可以实例化它并将其分配给该数组的一个元素:

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

实例化接口无法编译:

var bar = new IDynamicCode<string>();

您没有创建接口的实例;您正在创建一个数组,该数组可以容纳许多符合 IDynamicCode 的对象。最初,条目具有默认值,即 null

这不是在创建接口变量

这将创建一个数组,其中每个元素都实现接口。如果你写 x[0] = new IDynamicCode<string>(); 那么你会得到错误。所有元素都是 null,因此您需要为每个元素分配一个实现 IDynamicCode

的对象

当你打电话给

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

未调用构造函数。它们仅被声明。

只是一个有趣的旁注:

虽然在概念上不可能,但在语法上在特定情况下确实可以实例化接口

.NET 有一个叫做 CoClassAttribute 的东西,它告诉编译器将标记的接口解释为指定的具体类型。使用此属性将使以下代码完全有效并且不会引发编译时错误(请注意,这不是原始 post 中的数组):

var x = new IDynamicCode<string>();

此类属性的典型声明如下所示:

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

是否应该使用此属性,如果使用,那么在哪里使用?答案是"mostly never"!但是,在一些特定于 COM 互操作的场景中,这将成为一项有用的功能。

可以从以下链接阅读有关该主题的更多信息: