7

次のインターフェイスを検討してください。

interface Test<out T> where T : struct { }

エラーや警告なしでコンパイルされます。

この質問で説明し、共分散と反分散の FAQで言及されているように:

バリアンスは、型パラメーターが参照型である場合にのみサポートされます。

では、なぜ上記のインターフェースはコンパイルされるのでしょうか? 「out」キーワードで失敗する(または少なくとも警告する)のは理にかなっています。質問は要約すると思います-out上記の例でキーワードを使用すると違いが生じる場合はありますか?


更新: 上記のインターフェイスを見て気付かない開発者がすり抜けてしまう可能性がある、誤解を招く動作の例を次に示します。

typeof(IDummy).IsAssignableFrom(typeof(MyStruct)); // should return true
typeof(ITest<IDummy>).IsAssignableFrom(typeof(ITest<MyStruct>)); // returns false

コーダーが値の型に対してバリアンスが機能しないことを認識していない場合、キーワードtrueのために2 行目が返されることを期待しますが、返されることはありません。outこれはまさに、この質問をするように促したバグです...


コンパイルしても予期しない結果になるコードの別の例:

ITest<MyStruct> foo = ...;
var casted = (ITest<IDummy>)foo;

私はこれが機能することを期待していますが (参照型に対する共分散の制限については知りません)、System.InvalidCastException が発生します。

4

1 に答える 1

2

上記の例で out キーワードを使用すると違いが生じる場合はありますか?

いいえ。宣言で指定することはoutできますが、その型の特定のインスタンスを処理するときに実際にそれを活用することはできません。

このプログラムについては何も正しく動作しないため、開発者側の間違いを示している可能性が高いため、この動作を禁止するコンパイラの機能要求を本質的に求めています。その要求に対する応答は、(ほぼすべての他の機能要求と同様に) Microsoft がこれをオプションと見なしていなかったか、または考えていたとしても、時間と労力をかけてこの動作を積極的に禁止する価値がないと判断したというものです。

于 2013-05-24T16:12:10.053 に答える