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

时间:2010-05-10 01:40:30

标签: c# implicit-typing

我的印象是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 个答案:

答案 0 :(得分:14)

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

可以投出其中一个表达式:

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

...但我个人只是使​​用明确的形式:

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

或者,如果您明确声明obj1obj2obj3中的任何一个或全部为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.   然后进行输出类型推断   来自每个Ei的X型。最后,X   是固定的,结果类型S是   由此产生的共同类型   表达式。

答案 1 :(得分:3)

如果实例都可以转换为任何一个实例的类型,那么将使用该类型。所有实例都没有共同的任何类型是不够的,否则隐含数组初始化将始终成功,并且通常会生成不需要的new object[]数组。

答案 2 :(得分:0)

作为Skeet的回复的一点点补充:

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

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

这样可行,但请不要这样做:)只需定义数组类型并将new[]更改为new IWindsorinstaller[]即可。 在显式定义数组类型的情况下,它更具可读性。

答案 3 :(得分:0)

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可以是任何类