нулевое объединение примерно означает return x, unless it is null, in which case return y
Мне часто нужно return null if x is null, otherwise return x.y
я могу использовать return x == null ? null : x.y;
Неплохо, но то, null
что посередине, меня всегда беспокоит - кажется лишним. Я бы предпочел что-то вроде return x :: x.y;
, где то, что следует за ::
, оценивается, только если то, что ему предшествует, не оценивается null
.
Я считаю это почти противоположностью слияния нулей, как бы смешанной с краткой встроенной нулевой проверкой, но я [ почти ] уверен, что такого оператора в C # нет.
Есть ли в других языках такой оператор? Если да, то как это называется?
(Я знаю, что могу написать для этого метод на C #; я использую return NullOrValue.of(x, () => x.y);
, но если у вас есть что-нибудь получше, я тоже хотел бы это увидеть.)
return x ? x.y : NULL
. Ура для преобразования типов указателей в логические!Ответы:
В Groovy есть нулевой безопасный оператор разыменования (?.) ... Я думаю, это то, что вам нужно.
(Его также называют оператором безопасной навигации .)
Например:
Это даст нуль , если
person
,person.homeAddress
илиperson.homeAddress.postcode
равно нулю.(Теперь это доступно в C # 6.0, но не в более ранних версиях)
источник
null
, например:def bar = foo ?: "<null>"
Decimal? post = pre == null ? null : SomeMethod( pre );
. Было бы неплохо, если бы я мог уменьшить его до "Decimal? Post = pre :: SomeMethod (pre);"Мы рассматривали возможность добавления? в C # 4. Это не помогло; это функция «приятно иметь», а не «обязательно». Мы еще раз рассмотрим его для гипотетических будущих версий языка, но на вашем месте я бы не стал задерживать дыхание. С течением времени это вряд ли станет более важным. :-)
источник
Если у вас есть особый вид логической логики короткого замыкания, вы можете сделать это (пример javascript):
return x && x.y;
Если
x
имеет значение null, он не будет оцениватьсяx.y
.источник
Было просто правильно добавить это в качестве ответа.
Я предполагаю, что причина, по которой в C # нет такой вещи, заключается в том, что, в отличие от оператора объединения (который действителен только для ссылочных типов), обратная операция может дать либо ссылочный, либо тип значения (то есть
class x
с элементомint y
- поэтому, к сожалению, это будет непригоден для использования во многих ситуациях.Однако я не говорю, что не хотел бы это видеть!
Потенциальным решением этой проблемы было бы автоматическое преобразование оператором выражения типа значения с правой стороны в значение, допускающее значение NULL. Но тогда у вас есть проблема, что
x.y
где y - int, на самом деле вернет an,int?
что было бы болью.Другим, возможно, лучшим решением было бы, чтобы оператор возвращал значение по умолчанию (т. Е. Ноль или ноль) для типа с правой стороны, если выражение слева имеет значение NULL. Но тогда у вас возникают проблемы с различением сценариев, в которых фактически считывалось значение ноль / ноль
x.y
или было ли оно предоставлено оператором безопасного доступа.источник
int?
в качестве возвращаемого значения по умолчанию, и пользователь может изменить его на int, если захочет. Например, если я хочу вызвать какой-нибудь методLookup
со значением по умолчанию -1, в случае, если одна из моих ссылокnull
:foo?.Bar?.Lookup(baz) ?? -1
?. :
быть тернарным оператором, где правая часть должна быть того же типа, что и соответствующий член, указанный в середине?В Delphi есть оператор: (а не.), Который является нулевым.
Они думали добавить?. оператор в C # 4.0, чтобы сделать то же самое, но с блокировкой.
А пока есть IfNotNull (), который царапает, что чешется. Это конечно больше чем? или:, но он позволяет вам составить цепочку операций, которая не вызовет у вас исключение NullReferenceException, если один из членов имеет значение null.
источник
?.
функция языка C # 6.0, и да, она делает именно то, что здесь попросил OP. Лучше поздно, чем никогда ^^В Haskell вы можете использовать
>>
оператор:Nothing >> Nothing
являетсяNothing
Nothing >> Just 1
являетсяNothing
Just 2 >> Nothing
являетсяNothing
Just 2 >> Just 1
являетсяJust 1
источник
У Haskell есть
fmap
, что в данном случае, я думаю, эквивалентноData.Maybe.map
. Haskell является чисто функциональным, поэтому то, что вы ищете, будетЕсли
x
естьNothing
, это возвращаетсяNothing
. Еслиx
естьJust object
, это возвращаетсяJust (select_y object)
. Не так красиво, как точечная нотация, но, учитывая, что это функциональный язык, стили разные.источник
PowerShell позволяет ссылаться на свойства (но не вызывать методы) по нулевой ссылке, и она вернет значение NULL, если экземпляр имеет значение NULL. Сделать это можно на любой глубине. Я надеялся, что динамическая функция C # 4 будет поддерживать это, но это не так.
$x = $null $result = $x.y # $result is null $x = New-Object PSObject $x | Add-Member NoteProperty y 'test' $result = $x.y # $result is 'test'
Это некрасиво, но вы можете добавить метод расширения, который будет работать так, как вы описываете.
public static TResult SafeGet<T, TResult>(this T obj, Func<T, TResult> selector) { if (obj == null) { return default(TResult); } else { return selector(obj); } } var myClass = new MyClass(); var result = myClass.SafeGet(x=>x.SomeProp);
источник
public class ok<T> { T s; public static implicit operator ok<T>(T s) { return new ok<T> { s = s }; } public static implicit operator T(ok<T> _) { return _.s; } public static bool operator true(ok<T> _) { return _.s != null; } public static bool operator false(ok<T> _) { return _.s == null; } public static ok<T> operator &(ok<T> x, ok<T> y) { return y; } }
Мне часто нужна такая логика для строк:
using ok = ok<string>; ... string bob = null; string joe = "joe"; string name = (ok)bob && bob.ToUpper(); // name == null, no error thrown string boss = (ok)joe && joe.ToUpper(); // boss == "JOE"
источник
Создайте где-нибудь статический экземпляр вашего класса со всеми правильными значениями по умолчанию для членов.
Например:
z = new Thingy { y=null };
тогда вместо твоего
return x != null ? x.y : null;
ты можешь написать
return (x ?? z).y;
источник
Это добавляется в C # vNext (C # на базе Roslyn, выпуски с Visual Studio 2014).
Это называется нулевым распространением и указывается здесь как завершенное. https://roslyn.codeplex.com/wikipage?title=Language%20Feature%20Status
Он также указан здесь как полный: https://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/3990187-add-operator-to-c
источник
Так называемый «нулевой условный оператор» был введен в C # 6.0 и Visual Basic 14.
Во многих ситуациях он может использоваться как полная противоположность оператору объединения с нулем:
int? length = customers?.Length; // null if customers is null Customer first = customers?[0]; // null if customers is null int? count = customers?[0]?.Orders?.Count(); // null if customers, the first customer, or Orders is null
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-conditional-operators
источник