Подтвердить что ты не робот

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

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

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

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

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

У нас есть Tony Hoare, ранний пионер, который работал над Алголом, чтобы поблагодарить за это. Он скорее сожалеет об этом:

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

Я думаю, миллиард - это номер с низким шаром.

Ответ 3

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

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

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

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

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

Ответ 4

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

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

В 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/С# interop - но можно написать код Scala без использования этого факта, если null не разрешено "утечка" ).

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

Счастливое кодирование.

Ответ 5

Теперь оберните магическое слово С# -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;
    }
}

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

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

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

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

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

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


О, и за хороший вопрос ответ на ваш вопрос:

  • Текущая библиотека классов возникла после того, как ошибка Microsoft-Java и С# была построена как "улучшенная Java", поэтому изменение системы типов для удаления нулевых ссылок было бы большим изменением. Им уже удалось ввести типы ценностей и удалить ручной бокс!
  • В качестве введения типа значения microsoft много думает о скорости... Тот факт, что значение по умолчанию для всех типов соответствует нулевой заполнению, действительно важно для быстрой инициализации массива, например. В противном случае для инициализации массивов опорных значений потребуется особая угроза.
  • Без нулевого взаимодействия с C не было бы возможно, так что, по крайней мере, на уровне MSIL и в небезопасном блоке им нужно было бы выжить.
  • Microsoft хотела использовать фреймворк для VB6 ++ удаления Nothing, так как он вызывается в VB, радикально изменил бы язык, для пользователей уже потребовалось годы для перехода с VB6 на VB.Net, такое изменение парадигмы могло быть фатальным для языка.

Ответ 6

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

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

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

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

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

Ответ 7

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

Это похмелье с языков уровня C, где вы живете с явным манипулятором указателя. Современные декларативные языки (Mercury, Haskell, OCaml и т.д.) Получают совершенно безрезультатно. Там каждое значение должно быть явно построено. Идею "null" обрабатывают с помощью типов "option", которые имеют два значения: "нет" (соответствует нулевому) и "да (x)" (что соответствует ненулевому значению x). Вам нужно распаковать каждое значение параметра, чтобы решить, что делать, а значит: нет ошибок ссылки на нулевой указатель.

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

Ответ 8

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

Ответ 9

Чтобы обозначить концепцию ничто, поскольку 0 не является подходящим.

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

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

Ответ 10

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

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

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

Вкратце:

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

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

Ответ 11

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

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

Например,

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

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