相关疑难解决方法(0)

深度检查,是否有更好的方法?

注意:这个问题是在引进之前要求.?在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# null

128
推荐指数
6
解决办法
2万
查看次数

C#优雅的方法来检查属性的属性是否为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

87
推荐指数
10
解决办法
8万
查看次数

如何使用表达式树安全地访问可空对象的路径?

当我将反序列化的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)

c# tree lambda path expression-trees

6
推荐指数
1
解决办法
858
查看次数