帮助查找null引用异常源

属性或字段为 null

当创建某个类时,该类的字段和属性将自动初始化为其默认值。 引用类的默认值为 null(在 Visual Basic 中为 Nothing),在字段或属性值为 null 时调用父类的字段或属性的成员方法会导致 NullReferenceException。
在此示例中,突出显示的代码行将引发 NullReferenceException,因为 car 的 Engine 属性将自动初始化为 null。

public void NullReferenceFromProperty()
{
    var car = new Automobile();

    Console.WriteLine(car.Engine.ToString());
}

方法的返回值为 null

返回引用类型的方法可返回 null(在 Visual Basic 中为 Nothing)。 在引用为 null 时,调用返回的引用类型的方法或属性会导致 NullReferenceException。
在本示例中,突出显示的行将引发 NullReferenceException,因为对 BadGetEngineInfo 的调用在 NullReferenceFromMethodParameter 方法中返回 null 引用。

public EngineInfo BadGetEngineInfo()
{
    EngineInfo engine = null;
    return engine;
}

public void NullReferenceFromMethodReturnValue()
{
    var engine = BadGetEngineInfo();
    Console.WriteLine(engine.ToString());
}

集合或数组中的某个对象为 null

引用类型的列表或数组可能包含值为 null 的项。 为 null 的列表项的调用方法或属性会导致 NullReferenceException。
在此示例中,NullReferenceFromListItem() 中突出显示的代码行将引发 NullReferenceException,因为对 BadGetCarList 的调用将返回一个值为 null 的项。

public Automobile[] BadGetCarList()
{
    var autos = new Automobile[10];
    for (int i = 0; i autos.Length; i++)
    {
        if (i != 6)
        {
            autos[i] = new Automobile();
        }
    }
    return autos;
}

public void NullReferenceFromListItem()
{
    var cars = BadGetCarList();
    foreach (Automobile car in cars)
    {
        Console.WriteLine(car.ToString());
    }
}

由于存在某个条件,所以不创建对象

若在条件块中初始化引用类型,则在该条件为 false 时,将不会创建对象。
在本示例中,NullReferenceFromConditionalCreation 中突出显示的行将引发 NullReferenceException,因为它仅当 DetermineTheCondition() 方法返回 true 时才初始化 engine 变量。

public bool DetermineTheCondition()
{
    return false;
}

public void NullReferenceFromConditionalCreation()
{
    EngineInfo engine = null;
    var condition = DetermineTheCondition();
    if (condition)
    {
        engine = new EngineInfo();
        engine.Power = "Diesel";
        engine.Size = 2.4;
    }
    Console.WriteLine(engine.Size);
}

传递给方法的对象属性设置为 null

当对象作为参数按值传递给方法时(不在 C# 中使用 ref 或 out 关键字或在 Visual Basic 中使用 ByRef),该方法无法更改参数的内存位置(参数所指向的位置),但可以更改对象的属性。
在本示例中,NullPropertyReferenceFromPassToMethod 方法创建 Automobile 对象并初始化 Engine 属性。 然后它将调用 BadSwapCarEngine,将新对象作为参数传递。 BadSwapCarEngine 将 Engine 属性设置为 null,这会导致 NullPropertyReferenceFromPassToMethod 中突出显示的代码行引发 NullReferenceException。

public void BadSwapCarEngine(Automobile car)
{
    car.Engine = null;
}

public void (Automobile car)
{
    car.Engine = new EngineInfo("GAS", 1.5);
    BadSwapCarEngine(car);
    Console.WriteLine(car.Engine.ToString());
}

通过引用传递给方法的对象设置为 null

当你通过引用将引用类型作为参数传递给方法(使用 C# 中的 ref 或 out 关键字或者 Visual Basic 中的 ByRef 关键字)时,你可以更改该参数指向的内存位置。
如果通过引用将引用类型传递给某个方法,则该方法可以将引用的类型设置为 null(在 Visual Basic 中为 Nothing)。
在本示例中,NullReferenceFromPassToMethodByRef 中突出显示的行将引发 NullReferenceException,因为对 BadEngineSwapByRef 方法的调用将 stockEngine 变量设置为 null。

public void BadEngineSwapByRef(ref EngineInfo engine)
{
    engine = null;
}

public void NullReferenceFromPassToMethodByRef()
{
    var stockEngine = new EngineInfo();
    stockEngine.Power = "Gas";
    stockEngine.Size = 7.0;
    BadSwapEngineByRef(ref stockEngine);
    Console.WriteLine(stockEngine.ToString());
}

在开发期间查找 null 引用异常的源

使用数据提示、“局部变量”窗口和“监视”窗口来查看变量值
遍历调用堆栈以查找何处未初始化引用变量或未将其设置为 null
将条件断点设置为在对象为 null(在 Visual Basic 中为 Nothing)时停止调试

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值