dynamic
が、ジェネリック型パラメータとして使用された場合、object
と意味的に同等かどうか疑問に思っています。もしそうなら、変数や仮パラメータに値を代入するときに2つが異なるので、なぜこの制限が存在するのか不思議です。ジェネリック型パラメータとして使用すると、「ダイナミック」はすべてのタイプに関して共変で反例ではないのはなぜですか?
私はC#4.0で小さな実験を書いて、いくつかの詳細を分かち合いました。実験の
interface ICovariance<out T> { T Method(); }
interface IContravariance<in T> { void Method(T argument); }
class Covariance<T> : ICovariance<T>
{
public T Method() { return default(T); }
}
class Contravariance<T> : IContravariance<T>
{
public void Method(T argument) { }
}
興味深い内容::c1
とc2
と
class Variance
{
static void Example()
{
ICovariance<object> c1 = new Covariance<string>();
IContravariance<string> c2 = new Contravariance<object>();
ICovariance<dynamic> c3 = new Covariance<string>();
IContravariance<string> c4 = new Contravariance<dynamic>();
ICovariance<object> c5 = new Covariance<dynamic>();
IContravariance<dynamic> c6 = new Contravariance<object>();
// The following statements do not compile.
//ICovariance<string> c7 = new Covariance<dynamic>();
//IContravariance<dynamic> c8 = new Contravariance<string>();
// However, these do.
string s = new Covariance<dynamic>().Method();
new Contravariance<string>().Method((dynamic)s);
}
}
最初の二つの文の基本的な共変性と反変性が働いていることを証明している私はいくつかの単純なインタフェースと実装を定義しました。次にc3
とc4
を使用して、dynamic
をジェネリック型パラメータとして同じ方法で使用できることを示します。
c5
とc6
の文では、dynamic
からobject
への変換が常に有効であることがわかります。 object
は、他のすべてのタイプの祖先であるため、これはあまりにも驚くべきことではありません。
c7
とc8
の最終的な実験では、私が混乱し始めるところです。 dynamic
オブジェクトを返すメソッドは、string
オブジェクトを返すメソッドの代わりではなく、同様にstring
オブジェクトを受け入れるメソッドは、dynamic
オブジェクトを受け取ることができないことを意味します。代入とメソッド呼び出しの最後の2つのステートメントは、明らかにそうではないので、私の混乱を示しています。
私はこれについて少し考えて、これはのような、ランタイムエラーにつながる型変換の間足がかりとしてICovariance<dynamic>
を使用してから、プログラマのを防ぐためであるのか疑問に思っ:、
ICovariance<dynamic> c9 = new Covariance<Exception>();
ICovariance<string> c10 = c9;
// While this is definitely not allowed:
ICovariance<string> c11 = new Covariance<Exception>();
私たちは、とにかく型の安全性を失うので、これはdynamic
の場合には説得力に欠ける:
dynamic v1 = new Exception();
string v2 = v1;
は、別の言い方をすれば、質問は「なぜdynamic
のセマンティクスが間異なりありませんさ割り当てと共分散/ジェネリックとの反共?このいずれかの
希望Ericが訪問して啓示をくれます:) – Andrey
私は「召喚するエリック・リッペルト」を私ができる限り難しくキャストしようとしています。 – Amy
あなたは「キャスティング・エリック・リッペルートを召喚してください。" – Andrey