Почему в .NET существует null?

Почему в .NET значения могут быть нулевыми? Превосходно ли это по сравнению с гарантией, при которой все будет иметь значение, а ничто не будет равно нулю?

Кто-нибудь знает, как называется каждая из этих методологий?

В любом случае, я не очень разбираюсь в этом, но не имея ценности для всего, я бы упростил задачу с точки зрения простоты, то есть устранение нулевых проверок и возможность писать более оптимизированные алгоритмы, которые не должны разветвляться. для проверок.

Каковы плюсы и минусы каждого стиля с точки зрения производительности, простоты, параллелизма, соответствия требованиям будущего и т. Д.


person Joan Venge    schedule 01.03.2011    source источник
comment
Лично я бы предпочел проверить нулевое значение, чем поймать исключение, что, вероятно, вам пришлось бы сделать в противном случае.   -  person Metro Smurf    schedule 01.03.2011
comment
@Metro Smurf не обязательно, некоторые языки обрабатывают любые вызовы нулевой ссылки как черную дыру, например objective-c. Для меня плюсы и минусы такого подхода - более интересный вопрос.   -  person Matt Greer    schedule 01.03.2011
comment
Я бы хотел, чтобы @Eric Lippert взвесил такой вопрос ...   -  person Dan J    schedule 01.03.2011
comment
@Ravi Gummadi Nullable ничего не упрощает. К сожалению, проверки на null (хотя в некоторых случаях это удобно, но, возможно, усложняет ситуацию!). Он ограничен только типами значений и не имеет языковой поддержки для сопоставления с образцом: он все еще должен быть защищен ошибочными условными выражениями, если необходимо проверить нулевое состояние (например, когда просто получить значение или значение по умолчанию или ?? т работать).   -  person    schedule 01.03.2011
comment
Многие из перечисленных языков, которые не имеют понятия null или предпочитают обходиться без него, являются функциональными языками. Null - это объектно-ориентированная концепция. Возможность переменной представлять отсутствие объекта практически незаменима в объектно-ориентированном языке.   -  person snarf    schedule 01.03.2011
comment
Разве это не принадлежит программистам?   -  person Neal Tibrewala    schedule 01.03.2011
comment
@Snarfblam Я отвергаю это утверждение. null существует в основных языках объектно-ориентированного программирования (C ++, Java, C #, Python, Obj-C, JavaScript, даже Scala и т. Д.) - но в этих языках нет ничего, что требовало null - я подозреваю большая часть из-за 1) того, как работает язык X или 2) того, как работает язык X (нет, потому что это необходимая причина). Его можно было бы полностью заменить подходящим типом Option / Maybe на уровне языка (но тогда это был бы совершенно другой язык, но все же мог быть объектно-ориентированный объектно-ориентированный полиморфный подтип. !). Также рассмотрите NULL в не-OO-C.   -  person    schedule 01.03.2011
comment
@pst, я никогда не имел в виду, что null обязательно. Это просто чрезвычайно полезная концепция. Я также никогда не говорил, что объектно-ориентированный язык не может обойтись без null или что не-объектно-ориентированный язык не должен иметь null. Нулевые значения в C не имеют значения. Option / Maybe сводится к тому же, что и null, не так ли? Хотя я согласен с тем, что это звучит как отличная идея потребовать, чтобы переменные были явно объявлены как имеющие значение NULL. Мне было бы действительно интересно посмотреть, сколько концепций и шаблонов подходят без null.   -  person snarf    schedule 02.03.2011
comment
@Snarfblam null сам по себе является полезным понятием только постольку, поскольку он запрограммирован в памяти как таковой - необходимость знать, что чего-то не хватает, действительно полезно. Однако идиоматическая поддержка концепции null ... гораздо менее полезна для современного статически типизированного языка. В Java была предпринята попытка ввести @notnull, который указывает (imoho), что ничто не является общей проблемой типа, не решаемой с помощью null   -  person    schedule 06.03.2011
comment
@pst, я тебя слышу. Как я уже сказал, я согласен с тем, что это звучит как отличная идея потребовать, чтобы переменные были явно объявлены как имеющие значение NULL.   -  person snarf    schedule 08.03.2011
comment
Есть различие между языком C # и платформой .NET. Вы спрашиваете, почему null существует на платформе .NET, которая работает под всеми языками .NET, или вы спрашиваете, почему язык C # предоставляет программисту null? Разные вопросы.   -  person dthorpe    schedule 02.08.2012


Ответы (11)


Каким бы привлекательным ни был мир без null, он представляет большие трудности для многих существующих паттернов и конструкций. Например, рассмотрим следующие конструкции, которые потребовали бы серьезных изменений, если бы null не существовало.

  1. Создание массива ссылочных типов ala: new object[42]. В существующем мире CLR массивы будут заполнены null, что недопустимо. Здесь необходимо немного изменить семантику массива
  2. Это делает default(T) полезным только тогда, когда T является типом значения. Использование его в ссылочных типах или неограниченных дженериках запрещено.
  3. Поля в структуре, которые являются ссылочным типом, должны быть запрещены. Тип значения может быть инициализирован 0 сегодня в среде CLR, которая удобно заполняет поля ссылочных типов с помощью null. Это было бы невозможно в ненулевом мире, поэтому поля, которые являются ссылочными типами в структуре, должны быть запрещены

Ни одна из вышеперечисленных проблем не является неразрешимой, но они действительно приводят к изменениям, которые действительно бросают вызов тому, как разработчики склонны думать о кодировании. Лично мне хотелось бы, чтобы C # и .Net были разработаны с устранением null, но, к сожалению, это не так, и я полагаю, что проблемы, подобные приведенным выше, были немного связаны с этим.

person JaredPar    schedule 01.03.2011
comment
Спасибо, Джаред. Вот что мне интересно. Почему они не разработали NET без null? Кроме того, если бы они это сделали, разве это не было бы лучше с точки зрения производительности и простоты кода? Также не могли бы вы объяснить № 3, например, почему поля в структурах не разрешены? - person Joan Venge; 01.03.2011
comment
@ Джоан, предположим, у меня есть struct S1 { object field1; }. Каким будет значение field1 после выполнения выражения new S1()? Сегодня это было бы null, но в мире без null это было бы незаконно, поэтому либо инициализация структур по умолчанию, либо поля ссылочного типа в структурах должны быть незаконными. - person JaredPar; 01.03.2011
comment
Спасибо, Джаред, в этом есть смысл. Итак, если такие умные люди, как вы, работающие в MS, могли видеть пользу в мире без null, то кто принимает решения против этого, прежде чем они начнут проектировать .NET. Я предполагаю, что это то, что по какой-то причине обсуждалось и было решено против. - person Joan Venge; 01.03.2011
comment
@Joan, к сожалению, меня тогда не было рядом, и я не знаю подробностей дебатов (если они вообще были). Совместимость с Java была фактором в нескольких дизайнерских решениях, и я предполагаю, что она также повлияла на решение, касающееся null. Но опять же, я не знаю об этом напрямую. - person JaredPar; 01.03.2011
comment
Спасибо, Джаред, я благодарен тебе за это. - person Joan Venge; 01.03.2011
comment
Существенная поддержка дизайна .NET обеспечивается совместимостью с существующими библиотеками. Вот почему у нас есть указатели и типы значений со структурами, которые, помимо прочего, могут быть преобразованы непосредственно в собственные типы C. Это было небольшим отходом от идеологии Java (запрет на беззнаковые типы и указатели на функции). Это означает наличие null. - person Zac Bowling; 01.03.2011
comment
@JaredPar Вместо того, чтобы проектировать без null, может помочь языковая поддержка для ссылочных типов, не допускающих значения NULL, подобно тому, как мы поддерживаем типы значений, допускающие значение NULL. - person Sam Harwell; 18.01.2014
comment
Тип Maybe, подобный Haskell, поможет решить эти проблемы. Преимущество этого перед нулевыми значениями заключается в возможности контролировать, где разрешено значение «ничего», а где нет. В большинстве случаев вам не нужно или вы не хотите разрешать нули. - person Martin Capodici; 29.06.2016

У нас есть Тони Хоар, пионер, работавший над Алголом. благодарить за это. Он скорее сожалеет об этом:

Я называю это своей ошибкой на миллиард долларов. Это было изобретение нулевой ссылки в 1965 году. В то время я проектировал первую всеобъемлющую систему типов для ссылок на объектно-ориентированном языке (АЛГОЛ W). Моя цель состояла в том, чтобы гарантировать, что любое использование ссылок должно быть абсолютно безопасным, с автоматической проверкой компилятором. Но я не мог устоять перед соблазном вставить пустую ссылку просто потому, что это было так легко реализовать. Это привело к бесчисленным ошибкам, уязвимостям и системным сбоям, которые, вероятно, причинили боль и ущерб на миллиард долларов за последние сорок лет.

Думаю, миллиард - это мелочь.


ОБНОВЛЕНИЕ: у C # версии 8 и .NETCore есть достойное решение этой проблемы, проверьте ссылочные типы, не допускающие значения NULL.

person Hans Passant    schedule 01.03.2011
comment
Спасибо, Ганс. Это именно то, что я ищу. Я помню в одном из видео Андерса, где он также говорил, что они сделали ошибку в этом или что-то в этом роде, но я не помню видео, но оно было от C9. - person Joan Venge; 01.03.2011
comment
Ах, хороший справочник, но как бы выглядел мир без nulls? Как завершить список? - person Henk Holterman; 01.03.2011
comment
@Henk: Не то чтобы я обязательно выступал за это как за абсолют, но точно так же, как мы делаем с Nullable<T>: флаг. - person Adam Robinson; 01.03.2011
comment
@Henk - F # нравится ли это, и это действительно приятно работать с в контексте этого языка. - person Joel Mueller; 01.03.2011
comment
@Joel и под капотом F # фактически использует null для реализации некоторых своих конструкций (в частности, Option) :) - person JaredPar; 01.03.2011
comment
@Joan, @Hans, по памяти: какой-то крупный деятель из мира SQL однажды написал аналогичную ошибку о NULL. - person Henk Holterman; 01.03.2011
comment
Я бы тоже хотел найти видео Андерса. Я не уверен на 100%, но почти уверен, что нет. - person Joan Venge; 01.03.2011
comment
@JaredPar - я в курсе. CLR - это то, что есть, под капотом. Но за рулем система типов сообщает мне, может ли данная функция возвращать или не возвращать значение, и заставляет меня иметь дело с возможностями таким образом, что мой код практически не может быть источником нулевой ссылки. исключение. Было бы неплохо, если бы библиотеки фреймворка были такими же надежными. - person Joel Mueller; 01.03.2011
comment
@Joel Я на 100% согласен. Я зашел так далеко, что ввел тип Maybe<T> во многие базы кода, над которыми я работаю. Я считаю, что в итоге получается намного лучший код. - person JaredPar; 01.03.2011
comment
@ Джаред: Что делает «Может быть»? - person Joan Venge; 01.03.2011
comment
@Joan предоставляет декларативный способ выражения ссылки: может быть null / отсутствует. Он разработан в стиле опционного типа F #. blogs.msdn.com/b/jaredpar/archive/2008/10/08/ - person JaredPar; 01.03.2011
comment
Я не понимаю, почему изобретение нулевого указателя было ошибкой. Наличие стандартного способа определения невозможности разыменования указателя кажется очень хорошей идеей. Стоимость во время выполнения указателя с одним распознаваемым нулевым значением во многих случаях меньше, чем стоимость разрешения более широкого разнообразия нулевых значений. Единственная ошибка дизайна, которую я вижу в отношении нулевых указателей, заключается в том, что многие компиляторы C позволяют индексировать нулевой указатель без перехвата, что приводит к недопустимому указателю, который больше не будет распознаваться как нулевой. - person supercat; 08.03.2011

Это напоминает мне эпизод из серии «Связи» Джеймса Берка, где монахи переводили арабский язык на латынь и впервые столкнулись с нулевой цифрой. Римская арифметика не имела представления для нуля, но арабская / арамейская арифметика имела. «Почему мы должны писать письмо, чтобы ничего не указывать?» утверждали католические монахи. "Если это ничего, мы не должны ничего писать!"

К счастью для современного общества, они проиграли спор и научились записывать нулевые цифры в математике. ;>

Null просто представляет собой отсутствие объекта. Существуют языки программирования, в которых нет «нуля» как такового, но в большинстве из них все же есть что-то, что отражает отсутствие легитимного объекта. Если вы отбросите «null» и замените его чем-то под названием «EmptyObject» или «NullNode», это все равно null, только с другим именем.

Если вы удалите возможность языка программирования представлять переменную или поле, которое не ссылается на законный объект, то есть вы требуете, чтобы каждая переменная и поле всегда содержали истинный и действительный экземпляр объекта, тогда вы сделаете некоторые очень полезные и эффективные структуры данных неудобные и неэффективные, такие как построение связного списка. Вместо использования нуля для обозначения конца связанного списка программист вынужден изобрести «поддельные» экземпляры объектов, которые будут служить терминалами списков, которые ничего не делают, кроме как указывают «здесь ничего нет».

Здесь мы углубляемся в экзистенциализм, но: если вы можете изобразить присутствие чего-то, то разве нет фундаментальной потребности в том, чтобы иметь возможность представлять и его отсутствие?

person dthorpe    schedule 01.03.2011

Я предполагаю, что они существуют null в .NET, потому что он (C #) последовал за шагом в C ++ / Java (и только начал расширяться в более поздних версиях) и VB / J ++ (который стал VB.NET/J#) уже имел понятие значений "ничего", то есть .NET имеет null из-за того, что было, а не из-за того, что он мог Был.

В некоторых языках нет понятия null - null может быть полностью заменен типом, подобным Maybe - есть Something (объект) или Nothing (но это not null! Невозможно получить "Ничего" из "Может быть!")

В Scala с опцией:

val opt = Some("foo") // or perhaps, None
opt match {
   case Some(x) => x.toString() // x not null here, but only by code-contract, e.g. Some(null) would allow it.
   case _ => "nothing :(" // opt contained "Nothing"
}

Это делается языковым дизайном в Haskell (null невозможно ... вообще!) И поддержкой библиотеки и осторожным использованием, например, в Scala, как показано выше. (Scala поддерживает null - возможно, для взаимодействия Java / C # - но можно писать код Scala без использования этого факта, если только null не разрешено «просачиваться»).

Изменить: см. Scala: Option Pattern. , Scala: Option Cheat Cheet и SO: используйте Maybe Type в Haskell. В большинстве случаев разговор о Maybe в Haskell затрагивает тему монад. Я не буду утверждать, что понимаю их, но вот ссылка вместе с использованием Может быть.

Удачного кодирования.

person Community    schedule 01.03.2011
comment
Спасибо, разместили здесь соответствующий комментарий: Кстати, Haskell - единственный язык, у которого нет null? Но возможно? И что, возможно, никогда не возвращает null / ничего? - person Joan Venge; 01.03.2011
comment
@Joan Venge Я подозреваю, что есть и другие языки (особенно языки с зависимой типизацией) без null. Просто нет способа получить Ничего из Maybe (можно сохранить null в Option в Scala, но обычно этого не делается, поскольку это уменьшает огромное преимущество Option для начала - Некоторые (not_null_value) / Нет идиоматической кодировки :-) - person ; 01.03.2011
comment
Спасибо, pst, мне нужно будет узнать больше об этом материале Maybe, потому что я совсем с ним не знаком. Просто не понимаю сейчас: O - person Joan Venge; 01.03.2011
comment
@Joan Venge Я добавил несколько ссылок на свой пост. Обратите внимание, что ветви None / Nothing не имеют доступа к каким-либо новым значениям! Удачного кодирования. - person ; 01.03.2011
comment
Спасибо, pst. Я обязательно прочитаю твои материалы. Вы эксперт по Haskell? - person Joan Venge; 01.03.2011
comment
@ Джоан Венге Ха-ха. Нет, ни в коем случае - Привет, мир! примерно мой предел. Я неплохо справляюсь с Мягким введением в Haskell вплоть до Monads (глава 6?) - никогда не мог этого сделать. Скала, бородавки и все такое - это больше для меня. - person ; 01.03.2011
comment
Спасибо, pst. Я всегда слышу о Haskell, поэтому меня это заинтриговало. Но разве этому очень сложно научиться? Я надеялся, что он откроет мне кругозор, не будучи чрезвычайно сложным. - person Joan Venge; 01.03.2011
comment
@Joan Venge Просто подойдите к Haskell непредвзято. Я познакомил Haskell со своим (бывшим другом, работающим только с императивным C #) после того, как познакомил его со Scala (во время нашей программы CS мы стремились использовать разные языки для каждого назначения ;-). Сейчас он использует Scala для некоторых проектов (IMOHO: Scala ›C # [во многих случаях] ››› Java ;-), но он очень любит Haskell и использует его всякий раз, когда у него есть возможность. (Остается только многому научиться, и если время не будет потрачено зря, терять нечего ;-) - person ; 01.03.2011
comment
Спасибо, pst, ценю ваш совет. Я также работаю только с C #, я использовал некоторые языки, такие как Python, но не очень его фанат. Но вы думаете, что Scala лучше Haskell? Они в одной категории? А как насчет Лиспа? Я тоже это слышу часто, но не так часто, как Haskell. Также есть интерес к функциональным языкам, таким как F #, так что было бы здорово иметь в них некоторый опыт. - person Joan Venge; 01.03.2011
comment
@Joan Venge Мне нравится Scala (я предвзято): Scala - это статически типизированный объектно-ориентированный объект + множество функциональных конструкций + хорошая интеграция с Java. Это не идеальный язык: он не пытается им быть. Его сильная сторона (и недостаток) в том, что она предназначена для замены Java. Haskell - действительно функциональный язык. Он был разработан людьми, которые любят говорить о лямбда-исчислении и других академических темах, и, хотя он все еще не является окончательным языком, является чистым (ха-ха, каламбур!) Языком ;-) F # / Ocaml являются функциональными + OO-функциями; остров между Скалой и Хаскеллом. Python имеет динамическую типизацию и, следовательно, несопоставим. - person ; 01.03.2011

Хорошо, теперь перейдем к волшебному слову C # -without-null

class View
{
    Model model;        

    public View(Model model)
    {
        Console.WriteLine("my model : {0}, thing : {1}", this.model, this.model.thing);
        this.model = model;
    }
}

Что напечатано на консоли?

  • Ничего особенного при доступе к неинициализированному объекту не генерируется: Хорошо, назовите это NullReferenceException и это текущий мир.
  • Он не строится, пользователю нужно было указать значение при объявлении модели, см. Последний пункт, поскольку он дает тот же результат.
  • Некоторое значение по умолчанию для модели и какое-то значение по умолчанию для вещи: Хорошо, раньше с null у нас, по крайней мере, был способ узнать, был ли экземпляр правильным, теперь компилятор генерирует странные двойники, которые ничего не содержат, но все еще недействительны как модель объекты...
  • Что-то, определяемое типом объектов: лучше, поскольку мы могли бы определить конкретное недопустимое состояние для каждого объекта, но теперь каждый объект, который может быть недопустимым, должен независимо реализовать это вместе со способом идентификации этого состояния вызывающей стороной ...

Так что в основном для меня это, похоже, ничего не решает, чтобы удалить нулевое состояние, поскольку возможно недопустимое состояние все равно нужно управлять ...

О, купите путь, какое значение будет по умолчанию для интерфейса? Да, и абстрактный класс, что произойдет, когда метод будет вызван со значением по умолчанию, которое определено в абстрактном классе, но которое вызывает другой абстрактный метод? .... .... Зачем усложнять модель, это снова вопросы множественного наследования!

Одним из решений было бы полностью изменить синтаксис, чтобы перейти на полнофункциональный, где нулевой мир не выходит, только Maybes, когда вы хотите, чтобы они существовали ... Но это не C-подобный язык и многопарадигмальность из .Net будет потеряно.

Чего может не хватать, так это оператора с нулевым распространением, способного возвращать null в model.Thing, когда модель имеет значение NULL, например model.?.Thing


Ну и напоследок ответим на ваш вопрос:

  • Текущая библиотека классов развивалась после фиаско Microsoft-Java, и C # был создан как «улучшенная Java», поэтому изменение системы типов для удаления нулевых ссылок было бы большим изменением. Им уже удалось ввести ценностные типы и убрать ручной бокс!
  • Как видно из введения типа значения, Microsoft много думает о скорости ... Тот факт, что значение по умолчанию для всех типов соответствует нулевой заливке, действительно важен, например, для быстрой инициализации массива. В противном случае инициализация массивов справочных значений потребовала бы особого внимания.
  • Без нулевого взаимодействия с C было бы невозможно, поэтому, по крайней мере, на уровне MSIL и в небезопасном блоке им нужно позволить выжить.
  • Microsoft хотела использовать фреймворк для VB6 ++, удалив Nothing, как он называется в VB, радикально изменил бы язык, пользователям уже потребовались годы, чтобы переключиться с VB6 на VB.Net, такое изменение парадигмы могло быть фатальным для языка.
person Julien Roncaglia    schedule 01.03.2011
comment
Да, не было бы ужасно, если бы программисты VB 6 не смогли понять, как установить для всех своих объектов значение Nothing? Ой, подожди ... - person Cody Gray; 01.03.2011

Ну, значения (переменные типа значения) могут быть только null, поскольку типы, допускающие значение NULL, были введены в Fx2.

Но я полагаю, вы имеете в виду:

Почему ссылки могут быть null?

Это часть полезности ссылок. Рассмотрим дерево или LinkedList, они были бы невозможны (не могли бы закончиться) без null.

Вы можете привести еще много примеров, но в основном null существует для моделирования концепции «необязательных» свойств / отношений.

person Henk Holterman    schedule 01.03.2011
comment
Мне кажется, что эти конструкции все еще могут существовать; вам просто понадобится что-то вроде объекта NullNode или чего-то подобного. Конечно, у меня такое чувство, что все, что вы могли бы придумать для решения этой проблемы, на самом деле было бы не лучше, чем сам null. - person Dan Tao; 01.03.2011
comment
@Dan: Да, но тогда мы бы спросили этот объект "терминатор" для его значения или его Next. Поверьте, я буду бухать ... за исключением. - person Henk Holterman; 01.03.2011
comment
Верно. В некоторых языках отсутствует понятие null - null может быть полностью заменено на тип типа «Может быть - есть что-то (объект)» или «Ничего» (но это не null! Нет способа получить Ничего из возможного!). Это делается дизайном языка в Haskell и поддержкой библиотеки в Scala (Scala поддерживает null - возможно, для взаимодействия Java / C #, но можно писать код Scala без используя этот факт). - person ; 01.03.2011
comment
LMAO, отличный комментарий! Btw pst, Haskell - единственный язык, у которого нет null? Но возможно? И что, возможно, никогда не возвращает null / ничего? - person Joan Venge; 01.03.2011
comment
Да, я тоже об этом думал. Либо обращение к Next вызовет исключение, либо вернет тот же объект-терминатор. На самом деле, я думаю, что в мире, свободном от NULL, вероятно, что вместо проверки Next на null у вас будет что-то вроде bool TryGetNext(out Node next) метода; конечный узел просто вернет falsenext будет назначен самому себе). - person Dan Tao; 01.03.2011

Истерический изюм.

Это пережиток языков C-уровня, где вы живете за счет явных манипуляций с указателями. Современные декларативные языки (Mercury, Haskell, OCaml и др.) Вполне успешно обходятся без нулей. Здесь каждое значение должно быть явно построено. Идея «null» реализуется через типы «option», которые имеют два значения: «no» (соответствует null) и «yes (x)» (соответствует ненулевому значению x). Вы должны распаковать каждое значение параметра, чтобы решить, что делать, следовательно: нет ошибок ссылки на нулевой указатель.

Отсутствие нулей в языке избавляет вас от многих проблем, очень жаль, что идея все еще сохраняется в языках высокого уровня.

person Rafe    schedule 01.03.2011
comment
Null - это понятие, а не ключевое слово. Это относится к отсутствию, отсутствию присутствия, несуществованию. Идея присутствует, если у вас есть вариант типа. Тогда тип параметра аналогичен указателю, допускающему значение NULL, без средств управления памятью. - person Sion Sheevok; 01.03.2011
comment
@Sion - конечно, но ключ в том, что null или None, или как вам угодно, это допустимое значение только для ограниченного набора типов. Конечно, есть случаи, когда вы хотите использовать значение дозорного, но с тем же знаком есть и другие случаи, когда нулевые значения не имеют никакого смысла (и мы хотели бы, чтобы компилятор проверял, что используется ненулевое значение ). В C # нет ссылочных типов, не допускающих значения NULL, поэтому null является допустимым значением, даже если вы этого не хотите. - person kvb; 01.03.2011
comment
То же самое и с C ++. Вы не можете создать null int, null char, null bool или null ThisIsAnInstanceOfAClass. Единственный тип, допускающий значение NULL, - это указатель. - person Sion Sheevok; 01.03.2011
comment
@Sion Sheevok - разница в том, что тип параметра никогда не приведет к исключению нулевой ссылки. Более того, вы можете использовать алгебраические типы данных, чтобы однозначно различать неинициализированные, пустые и все остальное. Mercury даже зайдет так далеко, что проверит, учитывают ли ваши операторы switch один и тот же конструктор более одного раза или вообще не учитывают. Из-за того, что пришлось зарабатывать на жизнь переходом на C #, все кажется гораздо более примитивным. - person Rafe; 02.03.2011

Я тоже не знаком с альтернативами, но я не вижу разницы между Object.Empty и null, кроме null, чтобы вы знали, что что-то не так, когда ваш код пытается получить доступ к объекту, тогда как Object.Empty разрешает обработку для Продолжать. Иногда вам нужно одно поведение, а иногда другое. Отличие null от Empty - полезный инструмент для этого.

person Ritch Melton    schedule 01.03.2011

Для обозначения концепции небытия, поскольку 0 не подходит.

Теперь вы можете присвоить любому типу значения значение Null, определив тип, допускающий значение NULL.

Я думаю, что мы не можем всегда иметь значение для переменной, потому что сначала мы должны установить для нее какое-то значение по умолчанию, и здесь возникает вопрос, почему конкретное значение имеет преимущество перед другими.

person Ken D    schedule 01.03.2011
comment
Спасибо, а зачем нам ничто? Поскольку мы действительно ничего не можем сделать ни с чем, не так ли? - person Joan Venge; 01.03.2011
comment
Множество причин, одна из которых мне кажется, - позволить сборщику мусора знать, что нам больше не нужен объект. - person Ken D; 01.03.2011
comment
@Joan: Ты знаешь, что это ничто. - person Adam Robinson; 01.03.2011
comment
Но сборщик мусора не требует памяти на основе пустоты, верно? Например, если что-то не имеет ссылки на объект, значит, он знает, что нигде не используется. - person Joan Venge; 01.03.2011

Многие люди, вероятно, не могут осмыслить кодирование без нулей, и, если бы в C # не было нулей, я сомневаюсь, что он бы так прижился.

При этом хорошей альтернативой было бы, если вы хотите разрешить ссылку, допускающую значение NULL, тогда ссылка должна быть явно допускающей значение NULL, как с типами значений.

Например,

Person? person = SearchForPersonByFirstName("Steve");
if (person.HasValue)
{
    Console.WriteLine("Hi, " + person.Value.FullName);
}

К сожалению, когда вышел C # 1.0, не было концепции Nullable; это было добавлено в C # 2.0. Принуждение ссылок к значениям нарушило бы старые программы.

person jimmyfever    schedule 18.01.2014

null - это просто имя значения по умолчанию для ссылочного типа. Если null не было разрешено, то понятие «не имеет значения» не исчезло бы, вы бы просто представили его по-другому. Помимо специального имени, это значение по умолчанию также имеет особую семантику в случае неправильного использования - т.е. если вы относитесь к нему как к значению, а на самом деле его нет.

Если бы не было null:

  1. Вам нужно будет определить контрольные значения по умолчанию для ваших типов, которые будут использоваться, когда «нет значения». В качестве тривиального примера рассмотрим последний узел прямого односвязного списка.
  2. Вам нужно будет определить семантику для операций, выполняемых со всеми этими контрольными значениями.
  3. Среда выполнения будет иметь дополнительные накладные расходы на обработку контрольных значений. В современных виртуальных машинах, таких как те, которые используются .NET и Java, нет накладных расходов на проверку нуля перед вызовом большинства функций и разыменованием, потому что ЦП предоставляет специальные способы обработки этого случая, а ЦП оптимизирован для случаев, когда ссылки не равны нулю (например, предсказание ветвления).

В итоге:

  • Название изменится, а концепция - нет.
  • Бремя определения и передачи значения и семантики по умолчанию для случаев, когда у вас нет значения, возлагается на разработчиков и документацию для разработчиков.
  • Выполнение кода на современных виртуальных машинах столкнется с раздуванием кода и существенным снижением производительности для многих алгоритмов.

Проблемы с null, описанные Тони Хоаром, обычно связаны с тем, что до появления современных виртуальных машин в системах времени выполнения не было почти такой чистой обработки неправильно используемых значений null, как сегодня. Неправильное использование указателей / ссылок остается проблемой, но отследить проблему при работе с .NET или Java, как правило, намного проще, чем раньше, например С.

person Sam Harwell    schedule 18.01.2014
comment
IMHO, большая проблема с нулями исторически заключалась в том, что, хотя компиляторы C часто могли быть настроены вставкой нулевых проверок, чтобы гарантировать, что указатели с прямой ссылкой не были нулевыми, они не будут выполнять никаких таких проверок при выполнении арифметики указателей. Учитывая int *p, типичный код, сгенерированный 16-битным компилятором для p[5]=3;, может добавить 10 к p, затем проверить, не был ли результат ненулевым, и сохранить там 3, если это так. - person supercat; 27.04.2015