代码之家  ›  专栏  ›  技术社区  ›  Razor

实现接口的数组的隐式类型

  •  9
  • Razor  · 技术社区  · 14 年前

    我的印象是C编译器将隐式地键入一个基于类型的数组,这些类型都可以隐式地转换为。

    编译器生成 找不到隐式类型数组的最佳类型

    public interface ISomething {}
    
    public interface ISomething2 {}
    
    public interface ISomething3 {}
    
    public class Foo : ISomething { }
    public class Bar : ISomething, ISomething2 { }
    public class Car : ISomething, ISomething3 { }
    
    void Main()
    {
        var obj1 = new Foo();
        var obj2 = new Bar();
        var obj3 = new Car();
    
        var objects= new [] { obj1, obj2, obj3 };
    }
    

    我知道纠正这一点的方法是声明如下类型:

    new ISomething [] { obj1, ...} 
    

    但我在找一个隐藏式的帮助。

    4 回复  |  直到 6 年前
        1
  •  14
  •   Jon Skeet    14 年前

    C编译器考虑所有指定元素的类型集。它确实 考虑常见的基类型等。

    能够 转换其中一个表达式:

    var objects= new [] { obj1, obj2, (ISomething) obj3 };
    

    …但就我个人而言,我只会使用明确的形式:

    var objects= new ISomething[] { obj1, obj2, obj3 };
    

    或者,如果您明确声明 obj1 , obj2 obj3 作为类型 ISomething 在不更改数组初始化表达式的情况下也可以正常工作。

    根据C 3规范第7.5.10.4节:

    的数组创建表达式 第三种形式称为 隐式类型化数组创建 表达 . 它类似于 第二种形式,除了元素 数组的类型不是显式的 给予,但被认为是最好的 成套设备的通用类型(_§7.4.2.13) 数组初始值设定项中的表达式。

    第7.4.2.13节如下:

    在某些情况下,公共类型需要 为一组表达式推断。 特别是,元素类型 隐式类型化数组和返回 匿名函数的类型 用这种方法可以找到块体。 直观地,给定一组 表达式e1_em这个推论 应等同于调用 方法

    Tr M<X>(X x1 … X xm)
    

    以EI为论据。更多 准确地说,推论始于 带有非固定类型变量x。 然后进行输出类型推断 从每一个类型为x的EI。最后,x 是固定的,生成的类型S是 结果的公共类型 表达。

        2
  •  3
  •   Samuel Neff    14 年前

    如果所有实例都可以强制转换为任何一个实例的类型,则将使用该类型。对于所有实例来说,拥有任何共同类型都是不够的,否则隐式数组初始化总是成功的,并且常常会生成不需要的 new object[] 数组。

        3
  •  0
  •   Arman    10 年前

    作为对双向飞碟回答的补充:

    您可以将其中一个数组项强制转换为所需的类型(在本例中为Interface),或者如果只有一个该类型的元素(不是派生的,而是直接类型的)。如

    public static IWindsorInstaller[] MobileRestComponentInstallers
            {
                get
                {
                    return new []
                               {
                                     new RepositoryInstaller(),
                                     new AppSettingsInstaller(),
                                     // tens of other installers...
                                     GetLoggerInstaller() // public IWindsorInstaller GetLoggerInstaller()...
                               };
                }
            }
    

    这是可行的,但请不要这样做:)只需定义数组类型并更改 new[] new IWindsorinstaller[] . 显式定义数组类型更容易阅读。

        4
  •  0
  •   Sanjay Shrivastava    6 年前
    Do like this for Class object( UIViewController) initialization in var array:
    
    
    
     var page1 = new Class1();
     var page2 = new Class2();
     var pages = new UIViewController[] { page1, page2 };
    

    注意:这里uiviewController可以是任何类