null coalescing大致翻译为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
时进行评估。
我认为这是几乎与null合并相反,有点简洁,内联空检查,但我[几乎]确定C#中没有这样的运算符。
(我知道我可以在C#中为它编写一个方法;我使用return NullOrValue.of(x, () => x.y);
,但是如果你有更好的东西,我也希望看到它。) < / p>
答案 0 :(得分:60)
Groovy中有 null-safe解除引用运算符(?。)......我认为这就是你所追求的。
(它也被称为safe navigation operator。)
例如:
homePostcode = person?.homeAddress?.postcode
如果person
,person.homeAddress
或person.homeAddress.postcode
为空,则此值为空。
(现在是available in C# 6.0但在早期版本中没有)
答案 1 :(得分:33)
我们考虑过加入?到C#4。它没有削减;这是一个“很高兴”的功能,而不是“必备”功能。我们将再次考虑该语言的假设未来版本,但如果我是你,我不会屏住呼吸。随着时间的推移,它不太可能变得更加重要。 : - )
答案 2 :(得分:16)
如果你有一种特殊的短路布尔逻辑,你可以这样做(javascript示例):
return x && x.y;
如果x
为空,则不会评估x.y
。
答案 3 :(得分:7)
将此作为答案加入是正确的。
我想在C#中没有这样的东西的原因是因为,与合并运算符(仅对引用类型有效)不同,反向操作可以产生引用或值类型(即class x
成员int y
- 因此很遗憾在许多情况下无法使用。
该问题的潜在解决方案是,操作员可以自动将右侧的值类型表达式提升为可空。但是你遇到的问题x.y
其中y是一个int实际上会返回一个int?
,这将是一个痛苦。
另一个可能更好的解决方案是,如果左边的表达式为null,则操作符将返回右侧类型的默认值(即null或0)。但是,您有一些问题可以区分实际从x.y
读取零/ null的情况,或者它是否由安全访问运算符提供。
答案 4 :(得分:6)
Delphi有:(而不是。)运算符,它是null安全的。
他们正考虑添加一个?操作员对C#4.0做了同样的事情,但是得到了斩波块。
In the meantime, there's IfNotNull()哪种划痕痒。它肯定比大?或者:但它确实允许你组成一个操作链,如果其中一个成员为空,则不会对你产生NullReferenceException。
答案 5 :(得分:3)
在Haskell中,您可以使用>>
运算符:
Nothing >> Nothing
是Nothing
Nothing >> Just 1
是Nothing
Just 2 >> Nothing
是Nothing
Just 2 >> Just 1
是Just 1
答案 6 :(得分:3)
Haskell有fmap
,在这种情况下我认为相当于Data.Maybe.map
。 Haskell纯粹是功能性的,所以你要找的是
fmap select_y x
如果x
为Nothing
,则返回Nothing
。如果x
为Just object
,则返回Just (select_y object)
。不像点符号那么漂亮,但鉴于它是一种功能语言,风格是不同的。
答案 7 :(得分:2)
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);
答案 8 :(得分:1)
在某处创建一个类的静态实例,并为成员创建所有正确的默认值。
例如:
z = new Thingy { y=null };
然后代替你的
return x != null ? x.y : null;
你可以写
return (x ?? z).y;
答案 9 :(得分:1)
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"
答案 10 :(得分:1)
这是在C#vNext中添加的(Roslyn支持的C#,使用Visual Studio 2014发布)。
它被称为Null传播,在此处列为完整。 https://roslyn.codeplex.com/wikipage?title=Language%20Feature%20Status
此处也列为完整: https://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/3990187-add-operator-to-c
答案 11 :(得分:1)
所谓的&#34;零条件运算符&#34;已在C#6.0和Visual Basic 14中引入 在许多情况下,它可以与null-coalescing运算符完全相反:
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