C# 可空检查优化

C# nullable check optimization

谁能告诉我如何优化下面的代码。

if (report != null && 
    report.Breakdown != null &&
    report.Breakdown.ContainsKey(reportName.ToString()) &&
    report.Breakdown[reportName.ToString()].Result != null
    )

您可以使用 null 条件运算符,但只能在 C# 6 上使用

if ( report?.Breakdown?.ContainsKey(reportName.ToString()) == true &&
     report.Breakdown[reportName.ToString()].Result != null )

Ayman 的回答可能是您可以为 C# 6 做的最好的回答,因为在此之前,如果所有这些对象都可以为空,那么您所拥有的几乎是您可以做的最好的回答。

进一步优化的唯一方法是在调用代码之前检查这些对象是否为空,或者更好的是验证您的平台,因此如果值为空。

如果您只是从字典中获取值,您也可以使用空合并运算符“??”进行简化

示例:

MyDictionary['Key'] ?? "Default Value";

因此,如果该条目的值为空,您将获得默认值。

所以,如果这只是一次获取,我就去

var foo = 
     report != null && 
     report.Breakdown != null &&
     report.Breakdown.ContainsKey(reportName.ToString()) ?
     report.Breakdown[reportName.ToString()].Result ?? "Default" :
     "Default";

但是如果你真的在循环中做事,那么是的,你已经达到了最好的状态。

对于 C# 6 及更新版本,您可以这样做:

if (report?.Breakdown?.ContainsKey(reportName.ToString()) == true &&
    report.Breakdown[reportName.ToString()].Result != null)

你可以试试下面吗?也可能更好地将它发送到一个方法。

// unless report name is already a string
string reportNameString = reportName.ToString();
if ( report?.Breakdown?.ContainsKey(reportNameString) &&
     report.Breakdown[reportNameString].Result != null )
{
    // rest of the code
}

正如其他人所提到的,您可以使用 ?. 运算符来组合您的一些空检查。但是,如果你在优化性能之后,你应该避免双重字典查找(ContainsKey 和索引访问),而是使用 TryGetValue

MyType match = null;   // adjust type
if (report?.Breakdown?.TryGetValue(reportName.ToString(), out match) == true &&
    match?.Result != null)
{
    // ...
}