最も一般的な例私はcovariantly使用することはできませんcontravariantly-有効なタイプのパラメータが異なる派生型を注入し、基本型のラッパーにそれをキャストし、派生型のいくつかの読み書きのラッパーを構築関与している理由を説明することが分かってきました、 その後、ラップされた値を読み取る;引数型として排他的に使用される型パラメータを持つクラスを共存させることができないのはなぜですか?
class Base { public int base_property; }
class Derived : Base { public int derived_property; }
class OtherDerived : Base { public string other_derived_property; }
interface Wrapper<out T> {
void put(T v);
T pull();
}
Wrapper<Derived> derived_wrapper = new WrapperImpl<Derived>();
Wrapper<Base> cast_wrapper = (Wrapper<Base>)derived_wrapper;
cast_wrapper.put(new OtherDerived());
Derived wrapped = derived_wrapper.pull(); // Surprise! This is an OtherDerived.
これはなぜ無効かわかります。しかし、Wrapper
にpull
がなく、ラップするプロパティにプライベートゲッターがある場合はどうなりますか? (Wrapper<Base>)derived_wrapper
のキャストに関する問題は消えてしまいました。私はそれを置き換えるための問題を見つけることができません。機能は、汎用の最終的な具体的な種類を条件とするため
は具体的には、私はどのような方法を認識していませんよ。
class WrapperImpl<T> : Wrapper<T> where T : Base {
public void put(T v) {
if(typeof(T).Equals(Derived)) {
Console.WriteLine(v.derived_property); // Type `T' does not contain a
// definition for `derived_property'...
}
}
}
これは、これらの方法でその機能だけT
がに拘束されたタイプの性質を利用することができると信じて私をリード:当然、次のようなタイプをアサートすることは一切使用されません。包まれたプロパティは、元WrapperImpl
がDerived
(鋳造される前に)期待OtherDerived
であっても、何の方法がBase
が最も具体的なT
があることが保証されているので、包まれたプロパティがderived_property
を持っていることを期待することができませんでした。
は、私がここで何かが足りない、または多分これはその場でT
を具体化することはできないようにコンパイラの制限であるのですか?
(私はWrapper
ようなクラスは、いくつかの用途を見つけたが、分散のルールは非常に広範かつ抜本的な現れ、細かいルールが遊びに存在する場合、私は好奇心旺盛だと推測している。)