Re[5]: Ассоциативность "?."
От: _NN_ www.nemerleweb.com
Дата: 22.06.14 05:52
Оценка: 6 (1)
Здравствуйте, hardcase, Вы писали:

H>Здравствуйте, nikov, Вы писали:


N>>Я так понял, что он интересуется, что означает выражение a?.b.c в Nemerle.

N>>Или же это (a?.b).c (что может бросить NRE, если (a?.b) даёт null), или оно имеет смысл a ? («значение-a-если-не-null».b.c) аналогично Roslyn C# (ни свойство b, ни свойство c не вычисляются, если a даёт null).

H>Реализована вторая семантика: если a != null, то вычисляем цепочку дальше.

А если равен null ?

В C# 6 аналогичный код не будет приводить к NRE:
using System.Console;

def x = (null : string)?.Trim().Replace("a", "b");
WriteLine(x);

System.NullReferenceException


ncc :
    string text = null;
    string text2 = null;
    if (text != null)
    {
        text2 = text.Trim();
    }
    string value = text2.Replace("a", "b");
    Console.WriteLine(value);


ncc -debug- -optimize :
    string text = null;
    string text2 = null;
    if (text2 != null)
    {
        text = text2.Trim();
    }
    text2 = text.Replace("a", "b");
    Console.WriteLine(text2);
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[6]: Ассоциативность "?."
От: hardcase Пират http://nemerle.org
Дата: 23.06.14 13:21
Оценка:
Здравствуйте, _NN_, Вы писали:

H>>Реализована вторая семантика: если a != null, то вычисляем цепочку дальше.

_NN>А если равен null ?

Действительно, не было машины под рукой чтобы проверить.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[6]: Ассоциативность "?."
От: VladD2 Российская Империя www.nemerle.org
Дата: 24.06.14 16:32
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>В C# 6 аналогичный код не будет приводить к NRE:

_NN>
_NN>using System.Console;

_NN>def x = (null : string)?.Trim().Replace("a", "b");
_NN>WriteLine(x);
_NN>


Ну, наконец-то ты объяснил свою мысль. Нужно было привести данный пример в тематическом сообщении. Тогда и бадяги бы на 5 экранов не было бы.

Да, согласен, так лучше. Попробуй переделать. Возможно хватит изменения силы связывания (приоритетов) у препаратора ".?". Нужно сделать его меньшим чем у ".". Тогда код будет разбираться так:
def x = (null : string)?.(Trim().Replace("a", "b"));

что решит проблему (я надеюсь).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Ассоциативность "?."
От: Qodomoc Россия  
Дата: 24.06.14 20:52
Оценка:
Вопрос про short circuit.
Сейчас в C# 6
a?.b.c
превращается в
a != null ? a.b.c : null
.
Это предлагалось, чтобы не писать
a?.b?.c
.
Но эта запись превращается в
 (a != null && a.b != null) ? a.b.c : null
.
Т.е. чаще нужна проверка a на null, чем a.b, так что ли?
Re[8]: Ассоциативность "?."
От: nikov США http://www.linkedin.com/in/nikov
Дата: 24.06.14 21:26
Оценка: 6 (1)
Здравствуйте, Qodomoc, Вы писали:

Q>Сейчас в C# 6
a?.b.c
превращается в
a != null ? a.b.c : null
.

Q>Это предлагалось, чтобы не писать
a?.b?.c
.

Q>Но эта запись превращается в
 (a != null && a.b != null) ? a.b.c : null
.

Q>Т.е. чаще нужна проверка a на null, чем a.b, так что ли?

Неважно, что нужно чаще. Важно, что иногда нужно одно, а иногда другое. В существующем в Roslyn дизайне можно написать a?.b.c, если ты хочешь только проверить a на null (если a.b вдруг окажется null, то это ошибка, которую не нужно маскировать, передавая null дальше, а нужно бросить исключение). Но можно написать и a?.b?.c, если и a, и b могут оказаться null, и в таком случае ты хочешь заменить результат вызова c на null. Также ещё можно написать (a?.b).c, явно поставив скобки, и это будет третий вариант, который тоже имеет смысл в ограниченном числе случаев (например, когда .c — это .HasValue, .GetValueOrDefault() или extension method, позволяющий null в качестве первого аргумента). Roslyn позволяет тебе написать именно то выражение, которое тебе требуется по смыслу.
Re[7]: Ассоциативность "?."
От: nikov США http://www.linkedin.com/in/nikov
Дата: 24.06.14 21:27
Оценка: +1
Здравствуйте, VladD2, Вы писали:

VD>Возможно хватит изменения силы связывания (приоритетов) у препаратора ".?". Нужно сделать его меньшим чем у ".". Тогда код будет разбираться так:

VD>
VD>def x = (null : string)?.(Trim().Replace("a", "b"));
VD>

VD>что решит проблему (я надеюсь).

Я не думаю, что метод Trim() сам догадается, у какого объекта вызываться.
Re[8]: Ассоциативность "?."
От: VladD2 Российская Империя www.nemerle.org
Дата: 25.06.14 13:29
Оценка:
Здравствуйте, nikov, Вы писали:

N>Я не думаю, что метод Trim() сам догадается, у какого объекта вызываться.


Похоже ты прав. Тогда это без глобального переписывания не сделать. Парента менять мы не можем, а мембер-эксесы лежат как матрешки.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Ассоциативность "?."
От: nikov США http://www.linkedin.com/in/nikov
Дата: 01.10.14 01:39
Оценка:
Здравствуйте, nikov, Вы писали:

N>Бинарный оператор ? является лево-ассоциативным.


Кстати, недавно переделали на право-ассоциативный. Это довольно редко заметно на практике (как и с оператором ??), но в некоторых случаях даёт лучшую диагностику ошибок и позволяет избавиться от definite assignment errors в случаях вроде

int x; // no initializer
M(a?.N(out x)?.K(x));
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.