是否存在“相反”的情况?到空合并运算符? (ߪ用任何语言?)
null 合并大致翻译为返回 x,除非它为 null,在这种情况下返回 y
我经常需要如果 x 为 null,则返回 null,否则返回 xy
我可以使用 返回x == null ? null : xy;
不错,但是中间的 null
总是让我烦恼——它似乎是多余的。我更喜欢像 return x :: xy;
这样的东西,其中 ::
后面的内容只有在它前面的内容不 null
时才会被评估。
我认为这几乎与空合并相反,有点与简洁的内联空检查混合在一起,但我[几乎]确信没有C# 中的此类运算符。
还有其他语言有这样的运算符吗?如果是的话,它叫什么?
(我知道我可以用 C# 为其编写一个方法;我使用 return NullOrValue.of(x, () => xy);
,但如果您有更好的方法,我可以我也想看看。)
null coalescing translates roughly to return x, unless it is null, in which case return y
I often need return null if x is null, otherwise return x.y
I can use return x == null ? null : x.y;
Not bad, but that null
in the middle always bothers me -- it seems superfluous. I'd prefer something like return x :: x.y;
, where what follows the ::
is evaluated only if what precedes it is not null
.
I see this as almost an opposite to null coalescence, kind of mixed in with a terse, inline null-check, but I'm [almost] certain that there is no such operator in C#.
Are there other languages that have such an operator? If so, what is it called?
(I know that I can write a method for it in C#; I use return NullOrValue.of(x, () => x.y);
, but if you have anything better, I'd like to see that too.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(12)
Groovy 中有空安全解除引用运算符 (?.)...我想这就是您所追求的。
(它也称为安全导航操作符。)
例如:
如果
person
、person.homeAddress
或person.homeAddress.postcode
为 null,则返回 null。(现在在 C# 6.0 中可用,但在早期版本中不可用)
There's the null-safe dereferencing operator (?.) in Groovy... I think that's what you're after.
(It's also called the safe navigation operator.)
For example:
This will give null if
person
,person.homeAddress
orperson.homeAddress.postcode
is null.(This is now available in C# 6.0 but not in earlier versions)
更新:请求的功能已添加到 C# 6.0 中。下面 2010 年的原始答案应仅被视为具有历史意义。
我们考虑添加?。到 C# 4。它没有成功;这是一个“很好有”的功能,而不是一个“必须有”的功能。我们会再次考虑该语言的假设的未来版本,但如果我是你,我不会屏住呼吸等待。随着时间的推移,它不太可能变得更加重要。 :-)
UPDATE: The requested feature was added to C# 6.0. The original answer from 2010 below should be considered of historical interest only.
We considered adding ?. to C# 4. It didn't make the cut; it's a "nice to have" feature, not a "gotta have" feature. We'll consider it again for hypothetical future versions of the language, but I wouldn't hold my breath waiting if I were you. It's not likely to get any more crucial as time goes on. :-)
如果您有一种特殊的短路布尔逻辑,您可以执行以下操作(javascript 示例):
如果
x
为 null,则它不会计算xy
。If you've got a special kind of short-circuit boolean logic, you can do this (javascript example):
If
x
is null, then it won't evaluatex.y
.将其添加为答案感觉很正确。
我猜想 C# 中没有这样的东西的原因是因为,与合并运算符(仅对引用类型有效)不同,反向操作可以产生引用或值类型(即
class x
但是,我并不是说我不希望看到它!
> 与成员
int y
- 因此不幸的是, 运算符自动将右侧的值类型表达式提升为可空值,但是您会遇到一个问题,其中 y 是 int 的 xy 实际上会返回 int?运算符返回右侧类型的默认值(即 null 或零)。在区分实际从 xy 读取零/空值或是否由安全访问运算符提供的情况时存在问题。
It just felt right to add this as an answer.
I guess the reason why there is no such thing in C# is because, unlike the coalescing operator (which is only valid for reference types), the reverse operation could yield either a reference or value type (i.e.
class x
with memberint y
- therefore it would unfortunately be unusable in many situations.I'm not saying, however, that I wouldn't like to see it!
A potential solution to that problem would for the operator to automatically lift a value type expression on the right-hand-side to a nullable. But then you have the issue that
x.y
where y is an int will actually return anint?
which would be a pain.Another, probably better, solution would be for the operator to return the default value (i.e. null or zero) for the type on the right hand side if the expression on the left is null. But then you have issues distinguishing scenarios where a zero/null was actually read from
x.y
or whether it was supplied by the safe-access operator.Delphi 有 : (而不是 .) 运算符,它是空安全的。
他们正在考虑添加一个?。运算符到 C# 4.0 也可以做同样的事情,但是这已经成为了问题。
同时,还有 IfNotNull() 哪种抓痕会让人发痒。它肯定比 ? 大。或 :,但它确实允许您编写一系列操作,如果其中一个成员为 null,则不会引发 NullReferenceException。
Delphi has the : (rather than .) operator, which is null-safe.
They were thinking about adding a ?. operator to C# 4.0 to do the same, but that got the chopping block.
In the meantime, there's IfNotNull() which sort of scratches that itch. It's certainly larger than ?. or :, but it does let you compose a chain of operations that won't hork a NullReferenceException at you if one of the members is null.
在 Haskell 中,您可以使用
>>
运算符:Nothing >>>什么都没有
就是什么都没有
什么都没有>>> Just 1
是Nothing
Just 2 >>> Nothing
就是Nothing
Just 2 >>>只是 1
就是只是 1
In Haskell, you can use the
>>
operator:Nothing >> Nothing
isNothing
Nothing >> Just 1
isNothing
Just 2 >> Nothing
isNothing
Just 2 >> Just 1
isJust 1
Haskell 有
fmap
,在本例中我认为它相当于Data.Maybe.map
。 Haskell 是纯函数式的,所以您要寻找的是If
x
isNothing
, this returnsNothing
。如果x
是Just object
,则返回Just (select_y object)
。不像点表示法那么漂亮,但考虑到它是一种函数式语言,风格是不同的。Haskell has
fmap
, which in this case I think is equivalent toData.Maybe.map
. Haskell is purely functional, so what you are looking for would beIf
x
isNothing
, this returnsNothing
. Ifx
isJust object
, this returnsJust (select_y object)
. Not as pretty as dot notation, but given that it's a functional language, styles are different.PowerShell 允许您在 null 引用上引用属性(但不能调用方法),如果实例为 null,它将返回 null。您可以在任何深度执行此操作。我曾希望 C# 4 的动态功能能够支持这一点,但事实并非如此。
它并不漂亮,但您可以添加一个扩展方法,该方法将按照您描述的方式运行。
PowerShell let's you reference properties (but not call methods) on a null reference and it will return null if the instance is null. You can do this at any depth. I had hoped that C# 4's dynamic feature would support this but it does not.
It's not pretty but you could add an extension method that will function the way you describe.
我经常需要这种字符串逻辑:
I often need this logic for strings:
在某处创建类的静态实例,并为成员提供所有正确的默认值。
例如:
那么
你可以写成
Create a static instance of your class somewhere with all the right default values for the members.
For example:
then instead of your
you can write
此功能已添加到 C# vNext(Roslyn 支持的 C#,随 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
This is being added in C# vNext (Roslyn powered C#, releases with Visual Studio 2014).
It is called Null propagation and is listed here as complete.
https://roslyn.codeplex.com/wikipage?title=Language%20Feature%20Status
It is also listed here as complete:
https://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/3990187-add-operator-to-c
C# 6.0 和 Visual Basic 14 中引入了所谓的“空条件运算符”。
在许多情况下,它可以用作空合并运算符的相反操作:
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-conditional-operators
The so called "null-conditional operator" has been introduced in C# 6.0 and in Visual Basic 14.
In many situations it can be used as the exact opposite of the null-coalescing operator:
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-conditional-operators