是否存在“相反”的情况?到空合并运算符? (ߪ用任何语言?)

发布于 2024-09-03 04:36:25 字数 543 浏览 3 评论 0原文

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

作死小能手 2024-09-10 04:36:25

Groovy 中有空安全解除引用运算符 (?.)...我想这就是您所追求的。

(它也称为安全导航操作符。)

例如:

homePostcode = person?.homeAddress?.postcode

如果 personperson.homeAddressperson.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:

homePostcode = person?.homeAddress?.postcode

This will give null if person, person.homeAddress or person.homeAddress.postcode is null.

(This is now available in C# 6.0 but not in earlier versions)

揪着可爱 2024-09-10 04:36:25

更新:请求的功能已添加到 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. :-)

少跟Wǒ拽 2024-09-10 04:36:25

如果您有一种特殊的短路布尔逻辑,您可以执行以下操作(javascript 示例):

return x && x.y;

如果 x 为 null,则它不会计算 xy

If you've got a special kind of short-circuit boolean logic, you can do this (javascript example):

return x && x.y;

If x is null, then it won't evaluate x.y.

垂暮老矣 2024-09-10 04:36:25

将其添加为答案感觉很正确。

我猜想 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 member int 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 an int? 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.

╰ゝ天使的微笑 2024-09-10 04:36:25

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.

尸血腥色 2024-09-10 04:36:25

在 Haskell 中,您可以使用 >> 运算符:

  • Nothing >>>什么都没有就是什么都没有
  • 什么都没有>>> Just 1Nothing
  • Just 2 >>> Nothing 就是 Nothing
  • Just 2 >>>只是 1 就是只是 1

In Haskell, you can use the >> operator:

  • Nothing >> Nothing is Nothing
  • Nothing >> Just 1 is Nothing
  • Just 2 >> Nothing is Nothing
  • Just 2 >> Just 1 is Just 1
半夏半凉 2024-09-10 04:36:25

Haskell 有 fmap,在本例中我认为它相当于 Data.Maybe.map。 Haskell 是纯函数式的,所以您要寻找的是

fmap select_y x

If x is Nothing, this returns Nothing。如果xJust 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 be

fmap select_y x

If x is Nothing, this returns Nothing. If x is Just object, this returns Just (select_y object). Not as pretty as dot notation, but given that it's a functional language, styles are different.

放低过去 2024-09-10 04:36:25

PowerShell 允许您在 null 引用上引用属性(但不能调用方法),如果实例为 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);

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.

$x = $null
$result = $x.y  # $result is null

$x = New-Object PSObject
$x | Add-Member NoteProperty y 'test'
$result = $x.y  # $result is 'test'

It's not pretty but you could add an extension method that will function the way you describe.

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);
猫性小仙女 2024-09-10 04:36:25
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"
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; }
}

I often need this logic for strings:

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"
世界等同你 2024-09-10 04:36:25

在某处创建类的静态实例,并为成员提供所有正确的默认值。

例如:

z = new Thingy { y=null };

那么

return x != null ? x.y : null;

你可以写成

return (x ?? z).y;

Create a static instance of your class somewhere with all the right default values for the members.

For example:

z = new Thingy { y=null };

then instead of your

return x != null ? x.y : null;

you can write

return (x ?? z).y;
生生漫 2024-09-10 04:36:25

此功能已添加到 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

隐诗 2024-09-10 04:36:25

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://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:

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://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-conditional-operators

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文