9

我的印象是,C# 编译器将基于可以隐式转换为的类型隐式键入数组。

编译器 为隐式类型数组生成 No best type found

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

4 回答 4

14

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

可以使用以下表达式之一:

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

...但我个人只是使​​用显式形式:

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

或者,如果您显式声明任何或全部obj1obj2并且obj3作为 type 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 是表达式的结果公共类型。

于 2010-05-10T01:58:43.570 回答
3

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

于 2010-05-10T01:48:29.733 回答
0

作为对飞碟回复的一点补充:

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

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

这将起作用,但请不要这样做:) 只需定义数组类型并将其更改new[]new IWindsorinstaller[]. 明确定义数组类型更具可读性。

于 2014-02-20T16:23:45.133 回答
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 可以是任何类

于 2018-03-07T16:17:20.470 回答