你调用的对象是空的。 - 默认值

时间:2009-08-11 13:35:28

标签: c#

假设我有三个类A,B和C,它们以我可以通过A(即A.B.C)访问C到C的方式嵌套。如果我正在尝试访问C的简单属性,比如Id类型int,并且我没有在A中实现B的新实例(或B中的C),我会得到一个'对象引用未设置为实例一个东西。'错误。

我想知道的是,如果有一种简单的方式可以告诉我A.B.C.Id,如果你不能因为某些东西是空的,那么就给我一个默认值。

var myId = A.B.C.Id <some operator> -1;

目前我正在做这样的事情而且感觉太可怕了。

var myId = A == null ? -1 : A.B == null ? -1 : A.B.C == null ? -1 : A.B.C.Id;

7 个答案:

答案 0 :(得分:4)

通过A或B引用C或两者都打破了Law of Demeter,这是不好的做法。如果需要引用某些东西,那么就会有一个空的构造函数来构建那种连接。

答案 1 :(得分:2)

在C#中没有特殊的语法可以做你想做的事。

但是有一些建筑方法,如何做到这一点。

您可以使用Null Object Design Pattern 或者您可以使用允许null的扩展方法扩展A,B,C类:

var myId = A.BOrNull().COrNull().IdOrNull();

public class A {
    public B B { get; set; }
}
public static class AExtensionMethods {
    public static B BOrNull( this A a ) {
        return null != a ? a.B : null;
    }
}

public class B {
    public C C { get; set; }
}
public static class BExtensionMethods {
    public static C COrNull( this B b ) {
        return null != b ? b.C : null;
    }
}

public class C {
    public int Id { get; set; }
}
public static class CExtensionMethods {
    public static int? IdOrNull( this C c ) {
        return null != c ? (int?)c.Id : null;
    }
}

答案 2 :(得分:1)

查看dependency injection,当你创建一个新的A实例时,它将在A中创建C和A中的B.或者只是将代码放在类的构造函数中创建这样的实例。 (所以在A()中创建B,在B()中创建C

感觉错误的原因是,正如其他人所指出的那样,你不应该处于可能发生这种情况的情况。

答案 3 :(得分:1)

如果你必须深入研究,你可能想在A中创建一个属性,给你null或B.C.Id.

答案 4 :(得分:1)

这非常适合Null Object设计模式。

基本上,像这样定义NullB:

public class NullB : B
{
    public override C C
    {
        get { return new NullC(); }
    }
}

然后定义NullC:

public class NullC : C
{
    public override int Id
    {
        get { return 0; }
    }
}

这显然要求所讨论的类具有虚拟成员,但这样更安全。然后,当你有B和C的真实实例时,你只需使用并返回它们。

答案 5 :(得分:0)

您可以使用属性检查请求的类是否为null。如果是,它将创建该类的新实例。

class ClassA
{
    private ClassB m_ClassB = null;
    public ClassB B
    {
        get
        {
            //check if we already have an instance of the class.
            //if not create it
            if (m_ClassB == null)
            {
                m_ClassB = new ClassB();
            }
            return m_ClassB;
        }
    }
}

class ClassB
{
    private ClassC m_ClassC = null;
    public ClassC C
    {
        get
        {
            //check if we already have an instance of the class.
            //if not create it
            if (m_ClassC == null)
            {
                m_ClassC = new ClassC();
            }
            return m_ClassC;
        }
    }
}

class ClassC
{
    private int m_Id = 123;
    public int ID
    {
        get
        {
            return m_Id;
        }
    }
}

然后你可以像这样访问你需要的东西

 CLassA A = new ClassA();
 int id = A.B.C.ID;

答案 6 :(得分:-2)

您可以尝试以下代码:

var myId = -1;
try
{
  myId = A.B.C.Id;
}
catch (NullReferenceException e)
{
  myId = -1;
}