Возьмём эту самую функцию, GetPerson, и допустим, что C# поддерживает non-nullable типы. Она выглядела бы как-то так:
Person! GetPerson(Guid guid) { /*...*/ }
Далее введём другую функцию, которая допускает null:
Person FindPerson(Guid guid) { /*...*/ }
И лично я начинаю видеть проблему: Person/Person! означают одну и ту же сущность (некоего человека), но типы оказываются совершенно разными и не всегда взаимозаменяемыми. Это при том, что первоначально разница была лишь в различном поведении (контракте) функций. Не типов! Да, мы можем в своей собственной библиотеке ввести conventions, например, везде использовать только T! GetSomething() (парсер угловые скобки съедает). Но автор другой библиотеки рассудит иначе, и начнётся холивор get vs find, наподобие tabs vs spaces.
Мне это тоже интересно. Примера, в котором мне понадобились бы non-nullable типы, для себя я придумать так и не смог.
Где-то было мнение, что non-nullable типы — это симметричное дополнение к nullable типам, а язык, мол, стремится к балансу и симметричности. Но если поддержка nullables обусловлена практическими соображениями (DB — этого достаточно), то запрет null — это уже программная логика.
Null может быть и допустимым, и не допустимым значением. Точно так же, как и (int)-1 может иметь смысл (температура в °C), так и не иметь (K). Запрещать/фильтровать значения — это логика. Поэтому лично я не вижу смысла в non-nullable типах.
В клиенте почти наверняка будут востребованы фильтры — тот же поиск (по адресату, по телу письма и т.д.). Соответственно, «Важное» — это просто еще один фильтр.
Вставлю и я свои пять копеек: для меня тоже инбокс — помойка принятых (прочитанных и не) писем. Если мне нужны именно непрочитанные письма, то они будут выделены на фоне остальных или, например, будут находиться в отдельной «папке».
А первая моя мысль, если клиент поздравляет меня с пустым инбоксом: «Как пусто?! Где письма?».
Реквестирую опыт операции! Для хабра так такового — не формат, но, уверен, тема большинству очень близкая, и наверняка найдётся соответствующий непрофильный хаб.
> Решили, но свое решение не огласили. Могли бы, как минимум, прийти на выборы и испортить бюллетень.
Причём, что интересно, если бы пришли и забрали бюллетень с собой, результат был бы один. А если бы пришли, испортили бюллетень и опустили в урну, то результат получился бы другой :)
Насколько я помню, такие испорченные, но найденные, бюллетени играли против действующей власти, потому что всё равно +явка.
Поскольку "?." — это просто сахар для более многословной конструкции, то мне кажется, что если «point.X» — int, то и «point?.X» обязан быть int. На случай point == null справа от выражения должен стоять оператор "??". Тогда можно будет вернуть, например, 0.
Если же мы хотим nullable тип, то на это придётся указать явно:
int? x = point?.X ?? null;
либо
var x = (int?)(point?.X) ?? null;
По крайней мере лично я ожидал бы именно такого поведения.
Задумался над вашим ответом, думаю, я понял идею. Но заметьте — вы сказали «при компиляции CIL», а значит, даже если бы CIL тоже имел синтаксический сахар в виде возможности опустить тип, который и так известен, это всё равно компилятор — тот, кто занимается выводом типов ;)
> Я на выборы не ходил никогда и не пойду, потому что они не работают
Снова хочу вспомнить выбора мэра Москвы. Я, к сожалению, не знаю, откуда вы; вот в двух словах: кандидат от действующей власти С. (кстати, удивительно: когда дело доходит до выборов, очень многие начинают стесняться своей партии и идут самовыдвиженцами) победил в первом туре, набрав (по официальной информации) 51,37 %.
Две трети жителей Москвы тоже рассудили как и вы: выборы не работают, идти голосовать смысла нет. Итого как раз некоторого количества таких людей и не хватило, чтобы был объявлен второй тур. Оказалось, что результат С. отрицательно коррелировал с явкой :)
Конечно же, я почти уверен, что в случае второго тура там бы всё равно накрутили нужный результат. Было бы нужно 10 % — нашли бы. У нас опыт показывает, что подобные фальсификации, увы, переживаемы.
Person! GetPerson(Guid guid) { /*...*/ }
Далее введём другую функцию, которая допускает null:
Person FindPerson(Guid guid) { /*...*/ }
И лично я начинаю видеть проблему: Person/Person! означают одну и ту же сущность (некоего человека), но типы оказываются совершенно разными и не всегда взаимозаменяемыми. Это при том, что первоначально разница была лишь в различном поведении (контракте) функций. Не типов! Да, мы можем в своей собственной библиотеке ввести conventions, например, везде использовать только T! GetSomething() (парсер угловые скобки съедает). Но автор другой библиотеки рассудит иначе, и начнётся холивор get vs find, наподобие tabs vs spaces.
А вот контракты сюда подходят идеально.
14 нм — это Cherry Trail, запланированный на Q3 2014.
Где-то было мнение, что non-nullable типы — это симметричное дополнение к nullable типам, а язык, мол, стремится к балансу и симметричности. Но если поддержка nullables обусловлена практическими соображениями (DB — этого достаточно), то запрет null — это уже программная логика.
Null может быть и допустимым, и не допустимым значением. Точно так же, как и (int)-1 может иметь смысл (температура в °C), так и не иметь (K). Запрещать/фильтровать значения — это логика. Поэтому лично я не вижу смысла в non-nullable типах.
Пометить письмо важным (вроде закладок)?
Такая же система используется в браузерах (очевидно ;) и в личных сообщениях в соц. сетях.
> например, эстетика пустой папки, ощущение завершенных дел.
Это штука субъективная. Я в таком случае не отказался бы от возможности настроить, чтобы было так или иначе :)
А первая моя мысль, если клиент поздравляет меня с пустым инбоксом: «Как пусто?! Где письма?».
Причём, что интересно, если бы пришли и забрали бюллетень с собой, результат был бы один. А если бы пришли, испортили бюллетень и опустили в урну, то результат получился бы другой :)
Насколько я помню, такие испорченные, но найденные, бюллетени играли против действующей власти, потому что всё равно +явка.
Видимо, смутил пример использования.
Признаю, вы правы.
Таким образом,
«point?.X» — это int?, а
«point?.X ?? 3» — это int.
Да, логично.
Если же мы хотим nullable тип, то на это придётся указать явно:
int? x = point?.X ?? null;
либо
var x = (int?)(point?.X) ?? null;
По крайней мере лично я ожидал бы именно такого поведения.
Скорее всего, и тут будет своя ниша.
Рад, что я ошибся.
twistedoakstudios.com/blog/Post330_non-nullable-types-vs-c-fixing-the-billion-dollar-mistake
Для того, чтобы не было «колхоза с налчеками», уже есть code contracts.
А вот по поводу фильтров исключений я с вами соглашусь, тем более что их поддержка есть в VB.
К C# почему-то их до сих пор не прикрутили.
Снова хочу вспомнить выбора мэра Москвы. Я, к сожалению, не знаю, откуда вы; вот в двух словах: кандидат от действующей власти С. (кстати, удивительно: когда дело доходит до выборов, очень многие начинают стесняться своей партии и идут самовыдвиженцами) победил в первом туре, набрав (по официальной информации) 51,37 %.
Две трети жителей Москвы тоже рассудили как и вы: выборы не работают, идти голосовать смысла нет. Итого как раз некоторого количества таких людей и не хватило, чтобы был объявлен второй тур. Оказалось, что результат С. отрицательно коррелировал с явкой :)
Конечно же, я почти уверен, что в случае второго тура там бы всё равно накрутили нужный результат. Было бы нужно 10 % — нашли бы. У нас опыт показывает, что подобные фальсификации, увы, переживаемы.