9

私は、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

4 に答える 4

14

C# コンパイラは、指定されたすべての要素の型のセットを考慮します。共通の基本型などは考慮されません。

次のいずれかの式をキャストできます。

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

...しかし、個人的には、明示的な形式を使用します。

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

obj1あるいは、obj2およびの一部またはすべてをobj3type として明示的に宣言した場合ISomething、配列の初期化式を変更しなくても問題なく動作します。

C# 3 仕様のセクション 7.5.10.4 から:

3 番目の形式の配列作成式は、 暗黙的に型指定された配列作成式と呼ばれます。配列の要素型が明示的に指定されていないことを除いて、2 番目の形式に似ていますが、配列初期化子の式のセットの最も一般的な型 (§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

インスタンスをすべて任意の 1 つのインスタンスの型にキャストできる場合は、その型が使用されます。すべてのインスタンスが共通の型を持つだけでは十分ではありません。そうしないと、暗黙的な配列の初期化が常に成功し、望ましくないnew object[]配列が生成されることがよくあります。

于 2010-05-10T01:48:29.733 に答える
0

Skeet の返信へのわずかな追加として:

配列項目の 1 つを必要な型 (この場合はインターフェイス) にキャストするか、その型 (派生ではなく直接型) の要素が 1 つしかない場合にキャストできます。そのような

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

これは機能しますが、plsはそれを行いません:)配列タイプを定義し、をに変更するだけ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 に答える