注意:这个问题是在引进之前要求的.?在C#6/Visual Studio的2015年运营商.
我们都去过那里,我们有像cake.frosting.berries.loader这样的深层属性,我们需要检查它是否为空,所以没有例外.要做的是使用短路if语句
if (cake != null && cake.frosting != null && cake.frosting.berries != null) ...
Run Code Online (Sandbox Code Playgroud)
这不是很优雅,也许应该有一种更简单的方法来检查整个链,看看它是否出现了null变量/属性.
是否可以使用某种扩展方法或者它是一种语言功能,还是只是一个坏主意?
在C#中,假设您希望在此示例中从PropertyC中提取值,而ObjectA,PropertyA和PropertyB都可以为null.
ObjectA.PropertyA.PropertyB.PropertyC
如何使用最少量的代码安全地获取PropertyC?
现在我会检查:
if(ObjectA != null && ObjectA.PropertyA !=null && ObjectA.PropertyA.PropertyB != null)
{
// safely pull off the value
int value = objectA.PropertyA.PropertyB.PropertyC;
}
Run Code Online (Sandbox Code Playgroud)
做更像这样的事情会很好(伪代码).
int value = ObjectA.PropertyA.PropertyB ? ObjectA.PropertyA.PropertyB : defaultVal;
Run Code Online (Sandbox Code Playgroud)
可能甚至进一步崩溃与空合并运算符.
编辑最初我说我的第二个例子就像js,但是我把它改成了psuedo-code,因为它被正确地指出它在js中不起作用.
c# nullable nullreferenceexception null-conditional-operator
当我将反序列化的XML结果导入到xsd生成的对象树中并希望在该树abcdef中使用一些深层对象时,如果缺少该查询路径上的任何节点,它将给出异常.
if(a.b.c.d.e.f != null)
Console.Write("ok");
Run Code Online (Sandbox Code Playgroud)
我想避免为每个级别检查null,如下所示:
if(a != null)
if(a.b != null)
if(a.b.c != null)
if(a.b.c.d != null)
if(a.b.c.d.e != null)
if(a.b.c.d.e.f != null)
Console.Write("ok");
Run Code Online (Sandbox Code Playgroud)
第一个解决方案是实现Get扩展方法,该方法允许:
if(a.Get(o=>o.b).Get(o=>o.c).Get(o=>o.d).Get(o=>o.e).Get(o=>o.f) != null)
Console.Write("ok");
Run Code Online (Sandbox Code Playgroud)
第二个解决方案是实现Get(string)扩展方法并使用反射来获得如下所示的结果:
if(a.Get("b.c.d.e.f") != null)
Console.Write("ok");
Run Code Online (Sandbox Code Playgroud)
第三种解决方案,可以是实现ExpandoObject并使用动态类型来获得如下所示的结果:
dynamic da = new SafeExpando(a);
if(da.b.c.d.e.f != null)
Console.Write("ok");
Run Code Online (Sandbox Code Playgroud)
但是最后2个解决方案并没有带来强类型和智能感知的好处.
我认为最好的可能是可以用Expression Trees实现的第四个解决方案:
if(Get(a.b.c.d.e.f) != null)
Console.Write("ok");
Run Code Online (Sandbox Code Playgroud)
要么
if(a.Get(a=>a.b.c.d.e.f) != null)
Console.Write("ok");
Run Code Online (Sandbox Code Playgroud)
我已经实施了第一和第二个解决方案
以下是第一个解决方案的样子:
[DebuggerStepThrough]
public static To Get<From,To>(this From @this, Func<From,To> get)
{
var ret = default(To);
if(@this != null && !@this.Equals(default(From)))
ret = …Run Code Online (Sandbox Code Playgroud)