为什么接口变量实例化是可能的?
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 互操作的场景中,这将成为一项有用的功能。
可以从以下链接阅读有关该主题的更多信息:
- Who says you can’t instantiate an interface?
- Is it ok to (ab)use CoClassAttribute to provide a default implementation for an interface
- How does the C# compiler detect COM types?
据我所知,接口不能被实例化。
如果是这样,为什么下面的代码可以编译执行?它允许您创建可变接口。为什么这是可能的?
接口:
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 互操作的场景中,这将成为一项有用的功能。
可以从以下链接阅读有关该主题的更多信息:
- Who says you can’t instantiate an interface?
- Is it ok to (ab)use CoClassAttribute to provide a default implementation for an interface
- How does the C# compiler detect COM types?