Podstawowym powodem / problemem jest to, że projektanci specyfikacji CLS (która definiuje sposób interakcji języków z .net) nie zdefiniowali sposobu, w jaki członkowie klasy mogliby określić, że muszą być wywoływani bezpośrednio, a nie za pośrednictwemcallvirt , bez wykonującego kontrola zerowego odniesienia; nie dostarczył też wielu definicji struktur, które nie podlegałyby „normalnemu” boksu.
Gdyby specyfikacja CLS zdefiniowała takie środki, to .net byłby w stanie konsekwentnie podążać za wyprzedzeniem ustalonym przez Common Object Model (COM), zgodnie z którym odwołanie do ciągu zerowego traktowano semantycznie jako równoważne pustemu ciągowi, a dla innych zdefiniowane przez użytkownika niezmienne typy klas, które powinny mieć semantykę wartości, aby podobnie definiować wartości domyślne. Zasadniczo to, co by się stało, byłoby dla każdego członka String, np. LengthNapisane jako coś w rodzaju [InvokableOnNull()] int String Length { get { if (this==null) return 0; else return _Length;} }. Takie podejście zapewniłoby bardzo dobrą semantykę dla rzeczy, które powinny zachowywać się jak wartości, ale z powodu problemów z implementacją muszą być przechowywane na stercie. Największą trudnością przy takim podejściu jest to, że semantyka konwersji między takimi typami Objectmoże być nieco mętna.
Alternatywnym podejściem byłoby zezwolenie na definicję specjalnych typów struktur, które nie dziedziczyły, Objectale zamiast tego miały niestandardowe operacje boksu i rozpakowania (które konwertowałyby na / z jakiegoś innego typu klasy). Przy takim podejściu istniałby typ klasy, NullableStringktóry zachowuje się jak ciąg znaków, oraz niestandardowy typ struktury String, który przechowywałby pojedyncze prywatne pole Valuetypu String. Próba konwersji Stringna NullableStringlub Objectzwróci, Valuejeśli nie jest zerowa lub String.Emptyjeśli jest zerowa. Próba Stringużycia rzutowania na odwołanie inne niż null do NullableStringinstancji spowoduje zapisanie odwołania w Value(być może przechowywanie wartości null, jeśli długość wynosi zero); rzutowanie dowolnego innego odwołania spowodowałoby wyjątek.
Chociaż ciągi muszą być przechowywane na stercie, nie ma koncepcyjnego powodu, dla którego nie powinny zachowywać się jak typy wartości o wartości domyślnej innej niż null. Przechowywanie ich jako „normalnej” struktury, która zawierała odniesienie, byłoby skuteczne w przypadku kodu, który używał ich jako „łańcucha” typu, ale dodałoby dodatkową warstwę pośredniczości i nieefektywności podczas rzutowania na „obiekt”. Chociaż nie przewiduję dodania żadnej z powyższych funkcji w późniejszym terminie, być może projektanci przyszłych ram mogą rozważyć ich włączenie.