您的代码可能存在比需要检查空引用更大的问题。就目前而言,您可能违反了得墨忒耳法则。
得墨忒耳法则是启发式方法之一,例如不要重复自己,它可以帮助您编写易于维护的代码。它告诉程序员不要访问任何离直接作用域太远的东西。例如,假设我有以下代码:
public interface BusinessData {
  public decimal Money { get; set; }
}
public class BusinessCalculator : ICalculator {
  public BusinessData CalculateMoney() {
    // snip
  }
}
public BusinessController : IController {
  public void DoAnAction() {
    var businessDA = new BusinessCalculator().CalculateMoney();
    Console.WriteLine(businessDA.Money * 100d);
  }
}
该DoAnAction方法违反了得墨忒耳定律。在一个函数中,它访问 a BusinessCalcualtor、 aBusinessData和 a decimal。这意味着如果进行以下任何更改,则必须重构该行:
- 更改的返回类型
BusinessCalculator.CalculateMoney()。 
BusinessData.Money变化的类型 
考虑到had的情况,这些变化很有可能发生。如果在整个代码库中编写这样的代码,进行这些更改可能会变得非常昂贵。除此之外,这意味着您与 the和类型BusinessController都耦合。BusinessCalculatorBusinessData
避免这种情况的一种方法是像这样重写代码:
public class BusinessCalculator : ICalculator {
  private BusinessData CalculateMoney() {
    // snip
  }
  public decimal CalculateCents() {
    return CalculateMoney().Money * 100d;
  }
}
public BusinessController : IController {
  public void DoAnAction() {
    Console.WriteLine(new BusinessCalculator().CalculateCents());
  }
}
现在,如果您进行上述任何一项更改,您只需要再重构一段代码,即BusinessCalculator.CalculateCents()方法。您还消除BusinessController了对BusinessData.
您的代码遇到类似的问题:
interface IContact
{
    IAddress address { get; set; }
}
interface IAddress
{
    string city { get; set; }
}
class Person : IPerson
{
    public IContact contact { get; set; }
}
class Test {
  public void Main() {
    var contact = new Person().contact;
    var address = contact.address;
    var city = address.city;
    Console.WriteLine(city);
  }
}
如果进行了以下任何更改,您将需要重构我编写的 main 方法或您编写的 null 检查:
IPerson.contact变化的类型 
IContact.address变化的类型 
IAddress.city变化的类型 
我认为您应该考虑对代码进行更深入的重构,而不是简单地重写空检查。
也就是说,我认为有时遵循得墨忒耳法则是不合适的。(毕竟,这是一个启发式的规则,而不是一成不变的规则,尽管它被称为“法律”。)
特别是,我认为如果:
- 您有一些表示存储在程序持久层中的记录的类,并且
 
- 您非常有信心将来不需要重构这些类,
 
在专门处理这些类时,忽略得墨忒耳法则是可以接受的。这是因为它们代表了您的应用程序使用的数据,因此从一个数据对象到另一个数据对象是探索程序中信息的一种方式。在我上面的例子中,违反得墨忒耳定律造成的耦合要严重得多:我从靠近堆栈顶部的控制器通过堆栈中间的业务逻辑计算器一直到达可能的数据类在持久层。
我将这个潜在的例外带到了得墨忒耳法则中,因为使用、 和之类的名称Person,您的类看起来可能是数据层 POCO。如果是这种情况,并且您非常有信心将来永远不需要重构它们,那么在您的特定情况下,您可能可以忽略 Demeter 法则。ContactAddress