嵌套空值检查C#的简写

时间:2010-05-14 02:07:46

标签: c# language-features

据我所知,没有显着更优雅的方式来撰写以下内容....

string src;
if((ParentContent!= null)
    &&(ParentContent.Image("thumbnail") != null)
    &&(ParentContent.Image("thumbnail").Property("src") != null))
    src = ParentContent.Image("thumbnail").Property("src").Value

你认为应该有一个C#语言功能来缩短它吗?
如果是这样,它应该是什么样的?
例如,像延伸??操作

string src = ParentContent??.Image("thumbnail")??.Property("src")??.Value;

为相当人为的例子和我过度简化的解决方案道歉。

编辑......许多年后
现在这是一个名为“空传播运算符”的计划语言功能?. https://roslyn.codeplex.com/discussions/540883(谢谢@Brian)

5 个答案:

答案 0 :(得分:18)

没有内置语法来执行此操作,但您可以定义扩展方法来执行此操作:

R NotNull<T, R>(this T src, Func<T, R> f) 
    where T : class where R : class {
  return src != null ? f(src) : null;
}

现在,您可以按如下方式重写示例:

src = ParentContent.NotNull(p => p.Image("thumbnail")).
        NotNull(i => i.Property("src")).NotNull(src => src.Value);

它不像语法支持那样好,但我会说它更具可读性。

请注意,这会将NotNull方法添加到所有.NET类型,这可能有点不方便。您可以通过定义仅包含类型WrapNull<T> where T : class的值的简单包装类型T以及将任何引用类型转换为WrapNull并在其中提供NotNull的方法来解决此问题。 WrapNull类型。然后代码看起来像这样:

src = WrapNull.Wrap(ParentContent).NotNull(p => p.Image("thumbnail")).
        NotNull(i => i.Property("src")).NotNull(src => src.Value);

(因此,您不会使用新的扩展方法污染每种类型的IntelliSense)

通过更多的努力,您还可以定义LINQ查询运算符来执行此操作。这有点矫枉过正,但有可能写出这个(我不会在这里包含定义,因为它们有点长,但有可能有人感兴趣: - ))。

src = from p in WrapNull.Wrap(ParentContent)
      from i in p.Image("thumbnail").
      from src in i.Property("src")
      select src.Value;

答案 1 :(得分:16)

有人建议并且显然被团队拒绝了:

A bit more C# syntactic sugar for nulls

建议的语法看起来像a.?b.?c() - 非常有用,而且毫不含糊。

我也很想看到它,但看起来不会发生。也许如果有足够的人投票呢!

答案 2 :(得分:15)

我们考虑过C#4,但没有预算。这是很多人要求的一个很好的功能,所以也许我们会把它变成一个未来的假设语言版本。没有承诺。

答案 3 :(得分:1)

如果我错了,请纠正我,但这可以使用C#6.0解决null-conditional operator

string src = ParentContent?.Image("thumbnail")?.Property("src")?.Value;

如果在此值分配之前已使用src,则可以按如下方式使用它:

string src = ....;

// ...

src = ParentContent?.Image("thumbnail")?.Property("src")?.Value ?? src;

// ...

答案 4 :(得分:0)

它仍然有点不尽如人意,但我会这样写:

var src = ParentContent == null ? null
    : ParentContent.Image("thumbnail") == null ? null
    : ParentContent.Image("thumbnail").Property("src") == null ? null
    : ParentContent.Image("thumbnail").Property("src").Value;