有没有办法在动态/扩展中执行链接的空值检查? [英] Is there a way to perform a chained null check in a dynamic/expando?

查看:80
本文介绍了有没有办法在动态/扩展中执行链接的空值检查?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C#具有有用的空条件运算符。在此答案中也有很好的解释。

C# has the usefull Null Conditional Operator. Well explained in this answer too.

我想知道是否当我的对象是动态/扩展对象时,可以执行类似的检查。让我向您展示一些代码:

I was wondering if it is possible to do a similar check like this when my object is a dynamic/expando object. Let me show you some code:

给出该类层次结构

public class ClsLevel1
{
    public ClsLevel2 ClsLevel2 { get; set; }
    public ClsLevel1()
    {
        this.ClsLevel2 = new ClsLevel2(); // You can comment this line to test
    }        
}

public class ClsLevel2
{
    public ClsLevel3 ClsLevel3 { get; set; }
    public ClsLevel2()
    {
        this.ClsLevel3 = new ClsLevel3();
    }       
}

public class ClsLevel3
{
    // No child
    public ClsLevel3()
    {
    }
}

如果我执行这种链式空值检查,它会起作用

If i perform this kind of chained null check, it works

ClsLevel1 levelRoot = new ClsLevel1();
if (levelRoot?.ClsLevel2?.ClsLevel3 != null)
{
     // will enter here if you DO NOT comment the content of the ClsLevel1 constructor
}
else
{
     // will enter here if you COMMENT the content of the ClsLevel1 
}

现在,我将尝试使用动力学(ExpandoObjects)重现此行为

Now, i will try to reproduce this behaviour with dynamics (ExpandoObjects)

dynamic dinRoot = new ExpandoObject();
dynamic DinLevel1 = new ExpandoObject();
dynamic DinLevel2 = new ExpandoObject();
dynamic DinLevel3 = new ExpandoObject();

dinRoot.DinLevel1 = DinLevel1;
dinRoot.DinLevel1.DinLevel2 = DinLevel2;
//dinRoot.DinLevel1.DinLevel2.DinLevel3 = DinLevel3; // You can comment this line to test

if (dinRoot?.DinLevel1?.DinLevel2?.DinLevel3 != null)
{
     // Obviously it will raise an exception because the DinLevel3 does not exists, it is commented right now.
}

有没有一种方法可以模拟这种行为?我的意思是,检查一长串成员中是否有null?

Is there a way to simulate this behaviour with dynamics? I mean, check for a null in a long chain of members?

推荐答案

如果您想以更自然的方式支持它,您可以从DynamicObject继承并提供自定义实现:

If you want to support this in a more natural way you can inherit from DynamicObject and provide a custom implementation:

class MyExpando : DynamicObject
    {
        private readonly Dictionary<string, object> _dictionary = new Dictionary<string, object>();

        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            var name = binder.Name.ToLower();
            result = _dictionary.ContainsKey(name) ? _dictionary[name] : null;
            return true;
        }

        public override bool TrySetMember(SetMemberBinder binder, object value)
        {
            _dictionary[binder.Name.ToLower()] = value;
            return true;
        }
    }

测试:

 private static void Main(string[] args)
        {
            dynamic foo = new MyExpando();
            if (foo.Boo?.Lol ?? true)
            {
                Console.WriteLine("It works!");
            }
            Console.ReadLine();
        }

输出将为 It works!。由于Boo不存在,我们得到了一个空引用,以便Null条件运算符可以工作。

The output will be "It works!". Since Boo does not exist we get a null reference so that the Null Conditional Operator can work.

我们在这里要做的是返回 null 每次找不到属性时,都引用 TryGetMember 的输出参数,并且我们总是返回true。

What we do here is to return a null reference to the output parameter of TryGetMember every time a property is not found and we always return true.

这篇关于有没有办法在动态/扩展中执行链接的空值检查?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆