2016-11-28 24 views
3

我在代码中跳入了这样的事情,我并不知道如何阅读。将是很好,如果有人可以帮助我:)如何阅读这样的建筑?

return Company?.Call?.SingleOrDefault(cf => cf.Name == Client?.CallID) 
    ?? Company?.Call?.SingleOrDefault(cf => cf.IsDefault) 
    ?? new CallData(); 
+7

有些人就是喜欢看世界燃烧... –

+0

可能的情况下,返回的结果无效'Client'是零和'Company.Call'与名'null'存在 – fubo

+3

这就是你得到你的时候应用每个ReSharper建议。写起来很有趣,但无法读懂。有时代码需要明确。这里有五条商业规则,应该附带一条评论,指出或解释规范。几个'if()'语句不会伤害任何人。 – CodeCaster

回答

3

?.操作被称为空,条件运营商,也是一个新的功能,从C#6,并在2014年10月https://msdn.microsoft.com/en-us/library/dn986595.aspx

宣布第一部分:Company?.Call?.SingleOrDefault可被视为与此类似:

if (Company == null) 
{ 
    return null; 
} 
else if (Company.Call == null) 
{ 
    return null; 
} 
else 
{ 
    return Company.Call.SingleOrDefault(.... 
} 

但随后的原始编码器使用??空辅酶A lesce运算符,它至少自2007年以来一直是C#的一部分。这意味着如果??剩下的是null,请评估什么是??的权利,然后返回。

因此,代码基本上意味着:

  • 如果Companynull,返回new CallData()
  • 如果Company.Callnull,返回new CallData()
  • 如果到Company.Call.SingleOrDefault第一调用返回CallData实例(有Name属性的某个值),返回该实例
  • 如果第一次调用返回null,但第二个调用返回CallData实例(即默认的),返回该实例
  • 如果两个呼叫SingleOrDefault回报null,返回new CallData()

这件作品的代码有一些问题。

首先,它是不可读的,应该重构成更容易理解的东西。新的语言功能很好,但只有在负责任的情况下使用。

二:如果用相同的Name多个CallData情况下,SingleOrDefault会抛出异常,但有可能会在数据库中的防止这唯一索引。这同样适用于IsDefault财产 - 如果有一个以上的记录与IsDefault = true,该SingleOrDefault调用将抛出一个异常。

2

它斯普利特3倍的表达至上,??分离:

Company?.Call?.SingleOrDefault(cf => cf.Name == Client?.CallID) 
?? 
Company?.Call?.SingleOrDefault(cf=>cf.IsDefault) 
?? 
new CallData(); 

整个表达的返回值将是第一个表达式返回一个非空值。

在每个分段中,一旦使用?.访问的任何属性为null,整个表达式将评估为null

Null-conditional Operators

-1

首先,?运营商后类名或对象意味着该类可以为空。因此,一个?.将停止并返回null如果收到对象为空,否则,继续。 的??运营商将第一个非空元素分配给前一个序列中:

myA = aObj ?? new a(); 

延伸到:

if (aObj == null) 
{ 
    myA = new a(); 
} 
else if (new a() == null) 
{ 
    myA = aObj; 
} 

返回到您的代码。

return Company?.Call?.SingleOrDefault(cf => cf.Name == Client?.CallID) ?? Company?.Call?.SingleOrDefault(cf=>cf.IsDefault) ?? new CallData(); 

首先,我们可以看到它应该返回一些东西。左看右看,在“顶层”与?? new CallData();结束,所以我们可以假设它返回一个CallData

接下来,我们应该把它分解多行来了解发生了什么的每一步。

return //The function will return something. 
Company? // Is Company null? Yes, proceed : No, return null 
.Call? //Is call null? 
.SingleOrDefault //Select Item from list 
(cf => cf.Name == Client?.CallID) //Two checks here. Is client null? Is there any CallID the same as the Client's call ID? If both yes, returns the CallData. If no, returns null. 
?? //If any of the steps before returned null, default to the next one 
Company? //Company, or null 
.Call? //Call, or null 
.SingleOrDefault(cf=>cf.IsDefault) //Return the default one. 
?? //null? next one 
new CallData(); //Just make a new CallData() because the Client had none. 
+0

'INullable'不必执行。引用类型不实现'INullable',但仍可以与空条件运算符一起使用。 –

+0

我想说的是,如果你有什么东西,它类似于实现INullable。 – devRicher

+1

Nullable根本不会涉及到这一点,这是一个令人困惑和不相干的第一段。 –