更好的方法来检查深层对象引用的可空性?

时间:2017-12-12 10:31:46

标签: c# asp.net .net

public class A
{
    public B obj{get; set;}
    public A()
    {
        obj=new B();
    }
}
public class B
{
    public C obj{get; set;}
    public B()
    {
        obj=new C();
    }
}
public class C
{
    public D obj{get; set;}
    public C()
    {
        //obj=null;
        obj=new D();
    }
}
public class D
{
    public string s{get;set;}
    public D()
    {
        //s="Some string";
        s=null;
    }
}
public class Program
{
    public static void Main(string[] args)
    {
        A testObject = new A();
        if(testObject!=null && testObject.obj!=null && testObject.obj.obj!=null && testObject.obj.obj.obj!=null && testObject.obj.obj.obj.s !=null)
        {
            Console.WriteLine("String is not null");
            return;
        }

        //This will obviously fails if any of the object of A,B,C,D class is null
        //if(testObject.obj.obj.obj.s !=null)
        //{
        //    Console.WriteLine("String is not null");
        //    return;
        //}

        Console.WriteLine("String is NULL");
        return;
    }
}

在具有链式参考的示例中存在4个类(A,B,C,D)。 我只是想知道是否有更好的选项来检查可空性然后我在本例中使用的那个? (我想从类A的对象访问字符串变量's',所以在两者之间,如果任何对象为null,则抛出异常。我想知道是否有更好的方法,因为如果有更深的级别会变得更糟参考文献,虽然它们不是很推荐但是如果它存在的话。)

http://rextester.com/CGUU62557 (PS:我读了一些答案,通过REFLECTION来解决这个问题,但这对通用集合没有帮助。)

5 个答案:

答案 0 :(得分:0)

testObject!=null && testObject.obj!=null && testObject.obj.obj!=null && testObject.obj.obj.obj!=null等。

可以改写为

testObject?.obj?.obj?.obj?.obj != null

但我要说的是引用很多层深入到一个对象中,并且它的属性附加了“代码味道”警告。这意味着你的代码被耦合到对象的深层内部,如果它们只代表普通数据,可能不是问题,但如果它们代表复杂的行为可能是你想要避免的。

答案 1 :(得分:0)

我不确定这是否是您想要的,但您可以使用Null-Conditional Operator

if(A?.B?.C?.D == null)
{
   //Something was null
}

答案 2 :(得分:0)

通过将其设为null来测试它。

testObject.obj = null;

这不会抛出任何异常

if (testObject?.obj?.obj?.obj?.s != null)

此声明testObject?.obj?.obj?.obj?.s返回null作为结果

答案 3 :(得分:0)

您始终可以使用equals

if(!testObject.equals(null))
{
  //your logic
}

更好的方法是使用ReferenceEquals

    if(Object.ReferenceEquals(null, testObject))
    {
       //your logic
    }

如果对象为null,ReferenceEquals将返回true。

答案 4 :(得分:0)

您可以动态使用Reflection进行检查;

    private static bool CheckPropertiesAsNullRecursively(object obj)
    {
        if (obj == null)
        {
            return true;
        }
        var objType = obj.GetType();
        if (objType.IsPrimitive || objType == typeof(Decimal) || objType == typeof(String) || objType == typeof(Double))//You should compare the primitive types to determine them
        {
            return false;
        }
        var properties = objType.GetProperties();
        foreach (var propertyInfo in properties)
        {
            if (CheckPropertiesAsNullRecursively(objType.GetProperty(propertyInfo.Name).GetValue(obj)))
            {
                return true;
            }
        }
        return false;
    }

<强>用法

var val = CheckPropertiesAsNullRecursively(testObject);//If it returns true, at least one property should be null