Spe*_*nce 1 c# null language-features coding-style
我对编程风格和C#语言设计有一个疑问,我很想知道是否有更好的方法来做我正在做的事情.
如果你有一个复杂的数据对象,其属性可以为null,但你想检查或操作数据,如果它在那里,你不能写一个像这样的行
if(Myobject.MyNestedObject != null || Myobject.MyNestedObject.Property != null)
{
//code
}
Run Code Online (Sandbox Code Playgroud)
因为编译器实际上会调用两行代码来评估if语句.
相反,你必须(我相信)写道:
if(Myobject.MyNestedObject != null)
{
if(Myobject.MyNestedObject.Property != null)
{
//code
}
}
Run Code Online (Sandbox Code Playgroud)
有没有比这更好的风格?我正在尝试考虑如何使用null coalesce(??)但如果你尝试在同一个语句中使用MyNestedObject的任何东西,它仍会抛出.
更多信息:
L_01b4: ldarg.1
L_01b5: callvirt instance class [Myassembly]MyClass.MyObject [MyAssembly]MyClass::get_MyObject()
L_01ba: brtrue.s L_01cc
L_01bc: ldarg.1
L_01bd: callvirt instance class [MyAssembly]MyClass.MyObject [MyAssembly]MyClass::get_MyObject()
L_01c2: callvirt instance class [MyAssembly]MyClass.MyNestedObject [MyAssembly]MyClass.MyNestedObject::get_MyNestedObject()
L_01c7: ldnull
L_01c8: ceq
L_01ca: br.s L_01cd
L_01cc: ldc.i4.0
L_01cd: stloc.2
L_01ce: ldloc.2
L_01cf: brtrue L_0285
L_01d4: nop
Run Code Online (Sandbox Code Playgroud)
根据我的理解,它说L_01ba如果调用返回true,不是null或非0(即如果对象为null,则不采用分支,然后控制流程线性地继续).然后,这将执行L_01c2,它将抛出空引用异常,因为Myclass.MyObject为null.
我错过了什么.这是.net 3.5 C#编译器.
cha*_*rit 19
结合@Chris和@aJ答案:
我想你想要&&运算符,而不是||.
if (Myobject.MyNestedObject != null &&
Myobject.MyNestedObject.Property != null)
{
//code
}
Run Code Online (Sandbox Code Playgroud)
并且C#的&&运算符使用短路评估,因此如果第一个表达式返回false,则不会计算第二个表达式.
...