.NET値型が継承をサポートしない(インターフェイスの実装を無視する)技術的な理由があるかどうか疑問に思っています...値型が単一の基本クラスの継承を許可しない理由を一目で考えることはできません。
(つまり、おそらく、値型の継承は、継承階層が巨大になると悪いでしょうが、実際的な制限ではなく、実行時の制限があるかどうかはほとんど疑問に思っています。)
ありがとう。
.NET値型が継承をサポートしない(インターフェイスの実装を無視する)技術的な理由があるかどうか疑問に思っています...値型が単一の基本クラスの継承を許可しない理由を一目で考えることはできません。
(つまり、おそらく、値型の継承は、継承階層が巨大になると悪いでしょうが、実際的な制限ではなく、実行時の制限があるかどうかはほとんど疑問に思っています。)
ありがとう。
値型に割り当てられたメモリについて考えてみます。CLRは、どのフィールドが存在するかを知っているため、値型の変数に割り当てるスペースを正確に把握しています。より多くのフィールドを持つサブタイプ値で終わることはおそらくありません。
これで、値型の継承を行うことができます。これは、物事を切り捨てるだけです。
ExtendedValueType evt = new ExtendedValueType(...);
BaseValueType bvt = evt;
// Now you couldn't cast back to ExtendedValueType, because we'd have lost
// information
同様に、型情報が値自体に存在する場所がないため、拡張型によってオーバーライドされた仮想メソッドは、を介して呼び出されません。bvt
これは、すべてに関する限り、値は単なる値であるためですBaseValueType
。言い換えれば、多くの「自然な」継承機能が欠落しているため、多くの混乱が生じると思います。
値型が継承をサポートしない理由は、それらがメモリ内でどのように表現されるかによると思います。値型によって表されるデータのサイズとその結果としてのデータは、その構成フィールドに依存します。つまり、値型にintと文字列が含まれている場合、32ビットシステムの合計サイズは8、つまり4(intのサイズ)+ 4(ポインターのサイズ)になります。これが意味するのは、値型がメモリで表されるのはバイトのブロックであり、それ以上の情報はないということです。
ここで、クラスタイプとは対照的に、それらはすべてポインターのサイズ、または32ビットシステムでは4です。クラスタイプのインスタンスはポインタであるため、VMT(仮想メソッドテーブル)や親クラス情報への参照など、継承に必要なものを参照できます。これは値型では実行できないことであり、したがって値型が継承をサポートしないのはなぜですか。
それができるとしましょう。
一部の実装を再利用できるようになります。
しかし、継承の本当の利点は、置換とポリモーフィズムです。参照による使用が必要です。
そして、それが常にボクシングを伴うため、インターフェースの実装がサポートされる理由です。しかし、それは継承には効果がありません。