Здравствуйте, Kolesiki, Вы писали:
K>Увы, бестолковый пример к статье как раз и не иллюстрирует подобного профита.
Там вся статья бестолковая
Конкретно про nullables написано по мотивам творческого перепева ранних proposals.
Нынешний вариант выглядит вот так, прочитать стоит как минимум раздел "Opting In and Opting Out". Если есть желание обсуждать — прочитать лучше и всё остальное, там куча моментов уже поднималась.
K>И тут на ровном месте имеем проблему:
Нет никакой проблемы, для каждой библиотеки assumed nullability выставляется отдельно. Если совсем невтерпёж, то всегда можно пойти по следам решарпера и прикрутить external annotations: размечать public API nullability через аннотации в xml-файлике. В принципе, его можно даже автоматом генерить, flow analysis по il не сильно сложнее его же по ast рослина.
Больше деталей будет после текущего релиза, сейчас им заняты.
Здравствуйте, Kolesiki, Вы писали:
K>Да, и ещё один важный момент: искушение скидывать проверки на других. Тысячи библиотековаятелей с радостью нафигачат fun(Class! obj), лишь бы писать поменьше! Это превратит разработку в кошмар из проверок на пустом месте. K>Конечно, можно и не обращать внимания на warnings, но какой тогда смысл их иметь?
Здесь пахнет двойными стандартами. Тебе не нравится что автор библиотеки скидывает ответственность на тебя и хочешь спихнуть её на автора библиотеки.
К слову, а с переносом в C#8 не было планов по созданию белых списков для Nullable-аргументов?
Волшебной галки на проекте, которая считает все, условно говоря, String по-умолчанию не нулябельными и требует явного указания String? для возможности передать в неё Null?
Здравствуйте, LWhisper, Вы писали:
LW>К слову, а с переносом в C#8 не было планов по созданию белых списков для Nullable-аргументов? LW>Волшебной галки на проекте, которая считает все, условно говоря, String по-умолчанию не нулябельными и требует явного указания String? для возможности передать в неё Null?
...
It is possible to apply the following attribute to a declaration itself in order to opt in or opt out all consumers from nullability warnings originating from the declaration
Здравствуйте, LWhisper, Вы писали:
LW>Здесь пахнет двойными стандартами. Тебе не нравится что автор библиотеки скидывает ответственность на тебя и хочешь спихнуть её на автора библиотеки.
Автор библиотеки и так ОБЯЗАН отвечать за свой код — что код по кр. мере не взрывается на некорректных данных (как половина дотнета. Пример — похабнейшая реализация string.Substring).
Что я пытаюсь избежать, так это ещё и в своём коде городить чужие проверки только потому, что ленивая задница поставила [NonNull] атрибут. Спасибо, Синикс успокоил — можно подавлять эти капризы на уровне сборки.
Я вот перечитал трэд и всё ещё считаю, что никого этот NonNull не спасёт — этих предупреждений будет СЛИШКОМ МНОГО, чтобы честно на них реагировать.
Кроме того, всё зависит от задач — где-то и null — вполне допустимый возврат из функции, который в критичном месте можно проверить.
Здравствуйте, Kolesiki, Вы писали:
K>Я вот перечитал трэд и всё ещё считаю, что никого этот NonNull не спасёт — этих предупреждений будет СЛИШКОМ МНОГО, чтобы честно на них реагировать.
Если сделать правильно, то никаких предупреждений не будет, будет ошибка компиляции в том месте, где идет вызов потенциально нуллабельного объекта.
public class MyObj
{
public void Go()
{
// ...
}
}
public class MyClass
{
private MyObj Foo()
{
// ...
}
private [NotNull] MyObj Bar()
{
// ...
}
public void Test()
{
var fooResult = Foo();
// ошибка компиляции! fooResult может быть равно null
//fooResult.Go();
// а вот так - работаетif (fooResult != null)
fooResult.Go();
var barResult = Bar();
// работает без всяких проверок, так как barResult гарантированно не равен null
barResult.Go();
}
}
}
Вообще по уму надо бы конечно инвертировать — атрибут должен быть не NotNull, а Null. А not null должен быть у всех параметров по умолчанию. Короче так же, как и с value-типами.
Для компиляции старого говнокода ввести ключ -crapcode, который будет компилять в старом режиме.
Однако что-то мне подсказывает, что сделают через жопу и действительно будет убогое говно с предупреждениями (каким сейчас являются контракты).
Здравствуйте, AlexRK, Вы писали:
ARK>Вообще по уму надо бы конечно инвертировать — атрибут должен быть не NotNull, а Null. А not null должен быть у всех параметров по умолчанию. Короче так же, как и с value-типами.
Именно так оно и будет работать. Только вместо атрибута — синтаксический сахар с "MyObj?".
ARK>Однако что-то мне подсказывает, что сделают через жопу и действительно будет убогое говно с предупреждениями (каким сейчас являются контракты).
Не сделают, выше были ссылки на спецификацию.
Здравствуйте, Kolesiki, Вы писали:
K>Ведь null — это и есть индикатор, что что-то пошлó не так! Просто "взрыв на присвоении null" ничего не даст — нужно смотреть глубже в алгоритм и делать больше проверок/диагностик, чтобы null не вылезал, когда уже слишком поздно. Другими словами, non-null типы просто бесполезны! K>Если вы поняли мою идею (или её ошибочность), отпишитесь — интересная тема.
Идея такая. Представь себя на месте юзера. Вот пользуешься ты некоторой программой, попытался создать в ней новый документ и вдруг получил NullReferenceException. Что его вызвало — непонятно. Да и разработчики без дампа (или хотя бы stack trace) мало чем смогут помочь. Если бы вместо этого программа выдала "Exception: template file does not exist", ты бы сразу смекнул "наверное, это была прохая идея удалить normal.dot, чтобы освободить 1 килобайт на диске".
Теперь давай смотреть, почему вместо осмысленного exception-а вылез обычный NullReferenence. В 99% случаев паттерн будет такой:
SomeClass LoadSomething()
{
if(something)
return null;
}
//...
SomeClass obj = LoadSomething();
obj.DoSomething(); // <== Вот тебе бабушка и NullReferenceException
Почему это происходит? Заговор программистов? Попытка свергнуть режим? Тайное общество почитателей Null-а?
Нет, все проще. Человек, который писал LoadSomething(), подумал, что проверку на null сделают в вызывающем коде, а человек, который писал вызов, подумал, что LoadSomething() сам бросит осмысленный Exception.
Соответственно, что поменяется с приходом Non-nullable? LoadSomething() можно будет объявить как non-nullable, тогда попытка вернуть из него null словится на этапе компиляции. Соответственно, человек, добавивший проверку на if(something) это увидит и быстро поправит:
SomeClass! LoadSomething()
{
if(something)
throw new Exception("Something happened. You better run.");
}
С другой стороны, если в проекте договорятся что LoadSomething() сама ничего не бросает и возвращает null, то ее оставят как есть и тогда компилятор сможет с полным правом выдать warning, что вызывать obj.Something() без проверки obj на null нехорошо.
Как-то так.
P.S. Кстати, подобное давно реализовано в тех же Code Contracts от MS, но они за пределами research особо не популярны.
Здравствуйте, bazis1, Вы писали:
B>P.S. Кстати, подобное давно реализовано в тех же Code Contracts от MS, но они за пределами research особо не популярны.
Подобное реализовано в решарпере. А CodeContracts копает несколько глубже — статическим анализом пытается устранить рантайм проверки. Но качество реализации — увы, увы.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
K>Если вы поняли мою идею (или её ошибочность), отпишитесь — интересная тема.
Основная мысль в этой теме заключается в том что очень часто null используется в тех случаях когда вызывающему коду надо вернуть признак того что значения нету. Именно в этом случае использовать null не кошерно так как null в данном случае является implicit контрактом, т.е. возврат null вполне ожидаемая ситуация, но клиент об этом не знает так как явно это в контракте прописать невозможно.
Здравствуйте, AndrewVK, Вы писали:
ARK>>Вообще по уму надо бы конечно инвертировать — атрибут должен быть не NotNull, а Null.
AVK>По уму должно быть и то и то — и NotNull, и CanBeNull.
Здравствуйте, AndrewVK, Вы писали:
ARK>>Нет, NotNull не нужен.
AVK>Обоснуешь?
Это лишняя сущность, без которой можно обойтись в 100% случаев. Ее присутствие только вносит путаницу. Она не просто не нужна, она вредна. Если, конечно, разработчики не поставили себе цель превратить C# в огромную кучу мусора а-ля С++ (к чему, впрочем, он и так уверенно идет).
считаю, что нужно добавить значение Everything или God, это бы было в русле поддержки православия,
а так же более эффективно использовать два бита при помощи "семантического тензора".
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, bazis1, Вы писали:
B>>P.S. Кстати, подобное давно реализовано в тех же Code Contracts от MS, но они за пределами research особо не популярны.
AVK>Подобное реализовано в решарпере. А CodeContracts копает несколько глубже — статическим анализом пытается устранить рантайм проверки. Но качество реализации — увы, увы.
В CodeContracts в довесок еще и рантайм проверки идут. Правда непонятка чем это лучше, чем скажем Debug.Assert(something != null);
Здравствуйте, bazis1, Вы писали:
B>Здравствуйте, Kolesiki, Вы писали:
B>Теперь давай смотреть, почему вместо осмысленного exception-а вылез обычный NullReferenence. В 99% случаев паттерн будет такой: B>
B>P.S. Кстати, подобное давно реализовано в тех же Code Contracts от MS, но они за пределами research особо не популярны.
А меня вот запрягли эти контракты везде использовать. Был у меня TL, ярый джавист в третем поколении. Вот он прожить не мог, чтобы не ткнуть кого-то носом, если аннотация @Nullable или @NotNull не поставлена в Java коде. Начали мы писать наконец все на нативе к 8-ой версии продукта, и тут то мне и пришлось эти контракты сплошь и рядом тулить.
Кстати пример немного надуман, хотя действительно демонстрирует на пальцах суть. null обычно вылезает в не-инициализированных свойствах и полях. ТС должен знать, что для каждого объекта-члена-класса — дефолтовое значение=null. Вот тут обычно и вся засада. То список забыл создать, то какой-то объект. И если внутри метода вылезет error — вроде низзя без инициализации юзать переменную, то по неведомым причинам для полей и свойств такого компилер не умеет.
А есть еще библиотеки, написанные индусами, вроде HtmlAgility Pack, где вместо вброса эксепшена — лови null как результат метода.
Любой бывалый разработчик подтвердит — NullReferenceException (сокращенно NLP) — самая распространенная ошибка в любой проге. Так что давно пора эту фичу вносить.