基本的な理由/問題は、CLS仕様(言語が.netと対話する方法を定義する)の設計者が、クラスメンバーがそれらを介してではなく、直接呼び出す必要があることを指定できる手段を定義しなかったことです。callvirt
ではなく、ことです。 null参照チェック。また、「通常の」ボクシングの対象にならない構造を定義するという意味もありませんでした。
CLS仕様でこのような手段が定義されていれば、.netは、Common Object Model(COM)によって確立されたリードに一貫して従うことができます。同様にデフォルト値を定義するために値のセマンティクスを持っていると想定されるユーザー定義の不変クラス型。基本的に、何が起こるかはString
、たとえばのLength
ようなものとして書かれるために、の各メンバーのためになります[InvokableOnNull()] int String Length { get { if (this==null) return 0; else return _Length;} }
。このアプローチは、値のように動作する必要があるものに対して非常に優れたセマンティクスを提供しますが、実装の問題のため、ヒープに格納する必要があります。このアプローチの最大の難点は、そのようなタイプ間の変換のセマンティクスがObject
少し曖昧になる可能性があることです。
別のアプローチは、継承せずObject
、代わりにカスタムのボックス化およびボックス化解除操作(他のクラス型との間で変換される)を持つ特殊な構造体型の定義を許可することでした。このようなアプローチNullableString
では、stringと同じように動作するクラス型と、type String
の単一のプライベートフィールドValue
を保持するカスタムボックス構造体が存在しString
ます。変換しようとString
しNullableString
たりObject
返しますValue
null以外の場合、またはString.Empty
nullの場合。にキャストしようとするString
と、NullableString
インスタンスへの非null参照は参照をValue
格納します(長さがゼロの場合はnullを格納する可能性があります)。他の参照をキャストすると、例外がスローされます。
文字列はヒープに格納する必要がありますが、概念的には、null以外のデフォルト値を持つ値型のように動作してはならないという理由はありません。参照を保持する「通常の」構造としてそれらを格納することは、「文字列」型としてそれらを使用するコードには効率的でしたが、「オブジェクト」にキャストするときに間接層と非効率性の追加レイヤーが追加されました。現時点で.netが上記の機能のいずれかを追加することは想定していませんが、おそらく将来のフレームワークの設計者がそれらを含めることを検討するかもしれません。