Основна причина / проблема полягає в тому, що конструктори специфікації CLS (яка визначає, як мови взаємодіють з .net) не визначили спосіб, за допомогою якого члени класу могли б вказати, що їх потрібно викликати безпосередньо, а не через callvirt, без того, щоб абонент виконував нульова перевірка; а також не передбачав безлічі визначальних структур, які не підлягали б "нормальному" боксу.
Якби специфікація CLS визначала такий засіб, тоді .net міг би послідовно слідувати керівництву, встановленому загальною модель об'єкта (COM), згідно з якою нульова посилання рядка вважалася семантично еквівалентною порожній рядку та для інших визначені користувачем типи незмінних класів, які повинні мати значення семантики значень, щоб також визначати значення за замовчуванням. По суті, що трапилося б, було б для кожного члена String, наприклад, Lengthписати як щось подібне [InvokableOnNull()] int String Length { get { if (this==null) return 0; else return _Length;} }. Цей підхід запропонував би дуже приємну семантику для речей, які повинні вести себе як цінності, але через проблеми з реалізацією потрібно зберігати їх у купі. Найбільша складність цього підходу полягає в тому, що семантика перетворення між такими типами і Objectмогла б стати трохи мутною.
Альтернативним підходом було б дозволити визначення типів спеціальних структур, які не успадковували, Objectа натомість мали власні операції боксу та розпакування (які перетворювали б на / з іншого типу класу). При такому підході існували б тип класу, NullableStringякий веде себе так, як зараз це рядок, та власний структурований тип структури String, який би містив єдине приватне поле Valueтипу String. Спроба конвертувати a Stringв NullableStringабо Objectповернеться, Valueякщо не є null, або String.Emptyякщо null. Спроба привласнення до Stringненульової посилання на NullableStringекземпляр зберігатиме посилання в Value(можливо, зберігання нуля, якщо довжина дорівнює нулю); кастинг будь-якої іншої посилання кине виняток.
Незважаючи на те, що рядки повинні зберігатися в купі, концептуально немає причини, чому вони не повинні вести себе як типи значень, які мають ненулеве значення за замовчуванням. Зберігання їх як "нормальної" структури, на яку було посилання, було б ефективним для коду, який використовував їх як тип "рядок", але додав би додатковий шар непрямості та неефективності при передачі на "об'єкт". Хоча я не передбачаю .net додавати будь-яку з перерахованих вище функцій в цей пізній час, можливо, дизайнери майбутніх фреймворків можуть розглянути можливість їх включення.