【问题标题】:Why is interface variable instantiation possible?为什么接口变量实例化是可能的?
【发布时间】:2015-06-18 11:26:22
【问题描述】:

据我所知,接口无法实例化。

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

界面:

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

编码:

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

结果:

更新:

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

【问题讨论】:

  • 你创建了一个数组。

标签: c# .net variables interface instance


【解决方案1】:

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

您可以将任何实现IDynamicCode&lt;string&gt; 的类的实例分配给该数组。假设你有 public class Foo : IDynamicCode&lt;string&gt; { },你可以实例化它并将其分配给该数组的元素:

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

实例化接口不会编译:

var bar = new IDynamicCode<string>();

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      这不是创建接口变量

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

      【讨论】:

        【解决方案4】:

        只是一个有趣的旁注:

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

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

        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 = "");
        }
        

        是否应该使用这个属性,如果,那么在哪里?答案是“几乎从不”!但是,有几个特定于 COM 互操作的场景,这将提供有用的功能。

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

        【讨论】:

        • 你还没有实例化一个接口。您在 new-expression 中使用了接口类型,但正在实例化实现该接口的代理对象。值得注意的是,这是 new-expression 不会产生表达式中指定类型的对象的情况。
        • 完全正确。虽然这种表达式的语法可以被认为是“实例化一个接口”,但实际上一个具体的对象是通过 CoClassAttribute 的编译器知识在后台实例化的。
        • 你们俩都在说同样的话,但我更喜欢@Laurent LA RIZZA 的表述方式。在这种情况下,您看起来就像是在实例化一个接口,而实际上您是在指示编译器使用代理类作为接口的默认替换类型。由于 Java 高度关注封装,并且代码的 外观 可以独立于其功能进行定制(这很常见),我觉得在这种“奇怪”的情况下清楚是很重要的这不是黑客攻击,也不会以任何方式违反语言规则。
        【解决方案5】:

        当你打电话时

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

        不调用构造函数。它们只是被声明的。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-10-25
          相关资源
          最近更新 更多