Re[4]: { }
От: vmpire Россия  
Дата: 27.10.23 17:08
Оценка: +2 -1 :)
Здравствуйте, gandjustas, Вы писали:

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


G>Например: проверка схемы данных в JSON (нерегулярной структуры). Два поля, если присутствуют в любом элементе, то должны быть согласованы, одно из них — строковый идентификатор объекта, второе — этого же объекта из трех частей (проект, модуль, имя) в виде пути на сайте

G>
G>            if (obj.TryGetPropertyValue("entity", out var entityNode) &&
G>                obj.TryGetPropertyValue("dataPath", out var dataPathNode) &&
G>                entityNode is JsonValue entityValue &&
G>                dataPathNode is JsonValue dataPathValue &&
G>                entityValue.TryGetValue<string>(out var entityId) &&
G>                dataPathValue.TryGetValue<string>(out var dataPath))
G>            {
G>            }
G>


G>Написать то же самое без PM и out var займет в разы дольше.

Только вот когда в разы дольше, тогда можно дописать нормальную диагностику ошибки с сообщением, на каком элементе упал парсинг. А в приведённом примере единственное что можно написать, это
            else
            {
              throw new Exception("Что-то пошло не так");
            }

Так что это палка о двух концах.
Re[4]: GetByteCount()
От: Qbit86 Кипр
Дата: 27.10.23 17:15
Оценка:
Здравствуйте, _FRED_, Вы писали:

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


Так чтобы это количество стало известно, в современных API в BCL добавляют методы вроде GetByteCount() или GetMaxEncodedToUtf8Length(). Обычно в сценариях работы со span'ами, но и в обычных можно. Общая идея: не брать на себя аллокацию, пусть вызывающая сторона выделяет или берёт из пула.

_FR>P.S. С [tt] классно


А был бы Markdown, ещё лучше было бы!
Глаза у меня добрые, но рубашка — смирительная!
Re[2]: { }
От: BlackEric http://black-eric.lj.ru
Дата: 27.10.23 18:58
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Но кажется не очень удобной идея возврата null вместо List<Stage> (Guidelines for Collections / Collection Properties and Return Values):

_FR>

_FR>❌ DO NOT return null values from collection properties or from methods returning collections. Return an empty collection or an empty array instead.

_FR>The general rule is that null and empty (0 item) collections or arrays should be treated the same.

_FR>Потому как раз, что пользователю такого свойства или метода неудобно делать проверки на нулл, проще проверить, пуста ли коллекция.

_FR>Если вы возвращаете null чтобы не создавать лишний раз пустой список (когда он не нужен), то тут лучше изменить тип возвращаемого значения на, например, массив или ридонли интерфейс (от IEnumerable<> до IReadOnlyList<>) и возвращать Array.Empty<Stage>(); вметсо нулла. а пользователь уже, если и когда ему будет нужно, сможет скопировать полученную коллекцию в List<Stage>. Если такое лишнее копирование не устраивает, то нужна будет своя реализация, например, IReadOnlyList<> с методом ToList() которая для пустой "внутренней" коллекции создаст новый List<>, а для уже готового List<> его и вернёт.


У нас так часто в проекте. Возвращается null или пустой список или заполненный. Null как правило, если документ только создается.
https://github.com/BlackEric001
Re[5]: { }
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 27.10.23 19:51
Оценка:
Здравствуйте, vmpire, Вы писали:

V>Только вот когда в разы дольше, тогда можно дописать нормальную диагностику ошибки с сообщением, на каком элементе упал парсинг.

Во-первых это Exception-free код, там никаких путей исполнения через эксепшены нет. Если что-то падает, то никто не перехватывает.
Во-вторых текущий проверяемый JsonObject доступен в том числе для репортинга.

V>А в приведённом примере единственное что можно написать, это

V>
V>            else
V>            {
V>              throw new Exception("Что-то пошло не так");
V>            }
V>

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

V>Так что это палка о двух концах.

Конечно нет, просто кривизна рук разная.
Re[2]: { }
От: Разраб  
Дата: 28.10.23 00:22
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>❌ DO NOT return null values from collection properties or from methods returning collections. Return an empty collection or an empty array instead.


Логика требует, очевидно. 0 — ничего нет или не получилось?
null — как индикатор что что-то пошло нет так, или кидать исключение,
в любом случае придется как-то обработать 3-й вариант.
иначе получаем скрытую ошибку в программе.
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[4]: { }
От: Разраб  
Дата: 28.10.23 00:44
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>
G>void ProcessContent(JsonNode node)
G>{
G>    switch (node)
G>    {
G>        case JsonObject obj:
G>


G>Написать то же самое без PM и out var займет в разы дольше.

А не проще:
 case JsonObject obj:
    var x = obj.Deserialize<Option?>();
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[5]: `is` vs. `==`
От: Sinclair Россия https://github.com/evilguest/
Дата: 29.10.23 05:11
Оценка:
Здравствуйте, Qbit86, Вы писали:
Q>А вот сейчас было больно; я работаю с Unity
Не знаком с подробностями. Что не так с operator== в Unity?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[5]: { }
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 29.10.23 06:16
Оценка:
Здравствуйте, Разраб, Вы писали:

G>>Написать то же самое без PM и out var займет в разы дольше.

Р>А не проще:
Р>
Р> case JsonObject obj:
Р>    var x = obj.Deserialize<Option?>();
Р>


Не знаю, а пример код с той же семантикой какой будет?
Re[6]: `operator ==` в Unity
От: Qbit86 Кипр
Дата: 29.10.23 06:40
Оценка: 19 (2) :))
Здравствуйте, Sinclair, Вы писали:

S>Ведь если оператор сравнения перегружен каким-то нехорошим образом так, что он неверно проверяет на null, то у проекта проблемы тут не в code style. И при помощи is эти проблемы не решить.

S>Что не так с operator== в Unity?

У игровых объектов (или компонентов на них висящих) может быть статус «разрушен» — когда они удалены из дерева сцены, их ресусрсы освобождены, они не могут получать событий обновления, etc.
Так вот, вместо того, чтобы добавить в API свойство или метод IsAlive или IsDisposed, расработчики Unity переопределили operator ==, изменив его логику для случая сравнения с null. Проверка вида if (myGameObject == null) возвращает true не только когда ссылка is null, но и если объект разрушен; причём другого способа проверить разрушенность нет.
А если ты вызываешь методы движка на разрушенном объекте (имея на него ненулевую ссылку), то разработчики выбрасывают исключение типа NullReferenceException.

Абсолютно проклято.
Глаза у меня добрые, но рубашка — смирительная!
Отредактировано 29.10.2023 6:56 Qbit86 . Предыдущая версия . Еще …
Отредактировано 29.10.2023 6:53 Qbit86 . Предыдущая версия .
Re[7]: `operator ==` в Unity
От: Sinclair Россия https://github.com/evilguest/
Дата: 30.10.23 02:04
Оценка:
Здравствуйте, Qbit86, Вы писали:

Q>У игровых объектов (или компонентов на них висящих) может быть статус «разрушен» — когда они удалены из дерева сцены, их ресусрсы освобождены, они не могут получать событий обновления, etc.

Q>Так вот, вместо того, чтобы добавить в API свойство или метод IsAlive или IsDisposed, расработчики Unity переопределили operator ==, изменив его логику для случая сравнения с null. Проверка вида if (myGameObject == null) возвращает true не только когда ссылка is null, но и если объект разрушен; причём другого способа проверить разрушенность нет.
Q>А если ты вызываешь методы движка на разрушенном объекте (имея на него ненулевую ссылку), то разработчики выбрасывают исключение типа NullReferenceException.

Q>Абсолютно проклято.
На первый взгляд да. А в каких сценариях требуется отличать null-ссылку от ссылки на разрушенный объект, который уже удалён из дерева сцены?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[8]: Отличать
От: Qbit86 Кипр
Дата: 30.10.23 06:44
Оценка: 93 (3) +1
Здравствуйте, Sinclair, Вы писали:

S>На первый взгляд да. А в каких сценариях требуется отличать null-ссылку от ссылки на разрушенный объект, который уже удалён из дерева сцены?


Например, null-ссылка может быть признаком того, что её не проинициализировали — не привязали в Редакторе перетаскиванием одного игрового объекта в поле на другом объекте. Такую ситуацию надо обрабатывать иначе, чем просто ссылку на разрушенный объект. Anyway, атомарным кирпичиком должен быть IsDisposed(), из которого можно при необходимости собрать статический метод (расширения) IsNullReferenceOrDisposed(). А не наоборот, когда у тебя цепочка if (go is null) { … } else if (go == null) { … }, причём внутри второй проверке ещё раз повторно происходит и первая (ссылочное сравнение на null).

Сопряжённым источником фрустрации для многих разработчиков Unity (они в основном не специалисты в языке) было появление в очередной версии Unity поддержки null propagation и null coalescing в синтаксисе C#. Раньше они не задумывались, какой механизм лежит за тем, что их ссылки как бы «обнуляются» при смерти объекта. Многим казалось, что это такая магия рантайма (а не языка — переопределение оператора). И когда они стали заменять проверки if (go != null) go.Foo() на новый модный null propagation go?.Foo(), получали изменение семантики и неожиданный NullReferenceException (вместо хотя бы ObjectDisposedException).
Глаза у меня добрые, но рубашка — смирительная!
Отредактировано 30.10.2023 6:46 Qbit86 . Предыдущая версия .
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.