8

彼の本の中で、JonSkeetは暗黙のタイピングに関する7つの制限について言及しています。最後の2つについて説明する必要があります。

A.変数に含めるタイプは、初期化式のコンパイル時タイプです。
B.初期化式には、宣言されている変数は含まれません。

この本は、リリースされたのと同じ順序で資料をカバーしています(C#3の前のC#2)。この時点ではC#4は導入されていないため、Aはを参照していないと仮定しdynamicます。では、コンパイル時の型が初期化式の実行時の型と異なるのはいつですか?

Bに関しては、初期化式に宣言されている変数を含めることができるのはいつですか。

4

2 に答える 2

3

Bに関して、Henk は完璧な答えを出しました (編集: 現在は削除されています) int x = x = 1;。(私はxが初期化子の後まで宣言されたとは見なされないと思っていたでしょう。ああ、まあ。) 彼の答えは次のとおりでした:

int x = x = 1;   // Compiles
var y = y = 2;   // Does not compile

Aと、コンパイル時の型が実行時の型と一致しない場合についての質問について、それらが異なる例を次に示します。

var foo = fooFactory.GetFoo();

... そして fooFactory のそのメソッドは .... として実装されます。

public FooBase GetFoo() {
    return new FooSubtype();
}

ここで、fooの型は FooBase (インターフェイス、抽象クラス、または封印されていない具象クラスの場合があります) であり、(キャストなしで) その機能のみが利用可能です。明らかに、FooSubtype は FooBase を実装または継承しています。

実行時にfooが保持する型は、GetFoo() の実装を示しているため、ここで識別できますが、コンパイラによって検査されません。実際、実装が利用できない (別のアセンブリにある可能性がある) か、異なる可能性があります (仮想である可能性があります)。GetFoo() のコンパイル時の型、つまりfooの型を決定するには、メソッド宣言のみが関係します。

于 2012-05-23T19:41:22.603 に答える
2

Aに対する私の考え:

コンパイル時が実行タイプと異なるわけではありません。実行タイプがコンパイルタイプと同じでなくても(戻り値のタイプが抽象タイプであるメソッドのように)、実行で変数を宣言できないためです。とにかく明示的な入力で入力します。

ただし、コンパイル時に実際の動的型を定義できる場合でも、より抽象的な静的型で変数を宣言することができます。たとえば、次のように考えてください。

ISomething a = new MyOwnSomething();

なぜこれをしたいのですか?MyNewSomething明示的に実装する場合は、var で宣言された ifISomethingのように使用するためにキャストを作成する必要があります。ISomethingここでキャストはまだ行われていますが、かなり醜いものは見られません。

var a = new MyOwnSomething();
((ISomething)a).Whatever();

より不自然な例は、初期化コードが後で変更される可能性があるというものですが、この時点からは としてのみ使用aISomething、型の詳細MyOwnSomethingや実装している可能性のある他のインターフェイスを表示しないようにする必要があります。初期化タイプを変更してもコードが壊れることはありません。

于 2012-05-23T19:14:22.740 に答える