C# 为什么这会引发空对象异常

C# 为什么这会引发空对象异常,c#,nullpointerexception,C#,Nullpointerexception,我得到的对象引用未设置为对象的实例。:operator组装:0第157行。我不明白是什么引发了这个异常 LogFile.Info("order="+order.Id); if (order.Location != null) { LogFile.Info("order=" + order.Location.Address); } else { LogFile.Info("order location is null"); } LogFile.Info("order="

我得到的对象引用未设置为对象的实例。:operator组装:0第157行。我不明白是什么引发了这个异常

LogFile.Info("order="+order.Id);

if (order.Location != null)
{
    LogFile.Info("order=" + order.Location.Address);
}    
else
{
    LogFile.Info("order location is null");
}

LogFile.Info("order=" + order.Location.Latitude);
LogFile.Info("order=" +  order.IsResolved);
LogFile.Info("order user id=" + order.User.Id);
LogFile.Info("order ser name=" + order.User.Name);
LogFile.Info("order ser dest =" + order.Destination.Address);                       

line 157:
result = new OrderDataDriver
{
    OrderId = order.Id,
    Address = order.Location.Address,
    Lat = order.Location.Latitude,
    Lng = order.Location.Longitude,
    DestinationAddress = order.Destination.Address,
    DestinationLat = order.Destination.Latitude,
    DestinationLng = order.Destination.Longitude,
    IsCanceled = order.IsCanceled,
    IsPendingResponse = order.IsPendingResponse,
    IsResolved = order.IsResolved,
    UserId = order.User.Id,
    Message = order.MessageForDriver,
    UserName = order.User.Name,
    // IsAdvanceBooking = order.AdvenceBookingTime != null,
    AdvanceBookingTime = order.AdvenceBookingTime,
    AdvancePrice = order.CalculatedPrice,
    AdvanceDistance = order.CalculatedDistance,
    SecondsToRespond = 30,
    Status=order.DriverStatus
};

[DataContract]
public class OrderDataDriver
{

    [DataMember] public string Address { get; set; }
    [DataMember] public string Feedback { get; set; }
    [DataMember] public double Lat { get; set; }
    [DataMember] public double Lng { get; set; }
    [DataMember] public int UserId { get; set; }
    [DataMember] public string Status { get; set; }
    [DataMember] public bool? IsEligible { get; set; }
    [DataMember] public bool? IsCanceled { get; set; }
    [DataMember] public bool? IsResolved { get; set; }
    [DataMember] public bool? IsPendingResponse { get; set; }
    [DataMember] public bool? AllowsTracking { get; set; }
    [DataMember]
    public int OrderId { get; set; }
    [DataMember]


    public int App { get; set; }
    [DataMember]
    public int? PreferedDriver { get; set; }
    [DataMember]
    public bool IsAdvanceBooking { get; set; }
    [DataMember]
    public DateTime? AdvanceBookingTime { get; set; }
    [DataMember]
    public double? AdvancePrice { get; set; }
    [DataMember]
    public double? AdvanceDistance { get; set; }
    [DataMember]
    public string DestinationAddress { get; set; }
    [DataMember]
    public double DestinationLat { get; set; }
    [DataMember]
    public double DestinationLng { get; set; }
    [DataMember]
    public string Message { get; set; }
    [DataMember]
    public string UserName { get; set; }
    [DataMember]
    public int SecondsToRespond { get; set; }
}

如果属性为null,这些访问器中的任何一个都可能崩溃:

//If Location is null BOOM!!!
Lat = order.Location.Latitude,
Lng = order.Location.Longitude,

//If Destination is null BOOM!!!
DestinationAddress = order.Destination.Address,
DestinationLat = order.Destination.Latitude,
DestinationLng = order.Destination.Longitude,

如果属性为null,这些访问器中的任何一个都可能崩溃:

//If Location is null BOOM!!!
Lat = order.Location.Latitude,
Lng = order.Location.Longitude,

//If Destination is null BOOM!!!
DestinationAddress = order.Destination.Address,
DestinationLat = order.Destination.Latitude,
DestinationLng = order.Destination.Longitude,

将复杂对象初始化更改为如下内容:

var result = new OrderDataDriver();
result.blablah = foor.bar;
然后,您将得到一条更好的错误消息,其中包含您试图访问空对象属性的确切行号

这里是一个很好的地方,可以参考这个可爱的模式,它使开发人员的生活更轻松

将复杂对象初始化更改为如下内容:

var result = new OrderDataDriver();
result.blablah = foor.bar;
然后,您将得到一条更好的错误消息,其中包含您试图访问空对象属性的确切行号

这里是一个很好的地方,可以参考这个可爱的模式,它使开发人员的生活更轻松

由于可能为
null
的内容已被记录,因此应该更早捕获它们


除非你有一个有副作用的属性getter。这些都是纯粹的邪恶,所以要小心。另一种可能性是另一个线程更改了一个值。这更难证明。

因为可能是
null
的东西已经被记录下来了,它们应该早点被捕获


除非你有一个有副作用的属性getter。这些都是纯粹的邪恶,所以要小心。另一种可能性是另一个线程更改了一个值。这更难证明。

当您使用对象初始值设定项时,如

result = new OrderDataDriver { OrderId = order.Id, Address = order.Location.Address, Lat = order.Location.Latitude, Lng = order.Location.Longitude, };
不要期望行号(和列号,如果有的话)准确指出大括号
{}
中的哪些“属性赋值”导致异常。所有这些都转换为临时(不可见)变量属性的赋值。只有在一切顺利的情况下,临时变量才会复制到您的
结果
值中


在涉及对象初始值设定项的堆栈跟踪中,我也遇到了这种不便

result = new OrderDataDriver { OrderId = order.Id, Address = order.Location.Address, Lat = order.Location.Latitude, Lng = order.Location.Longitude, };
不要期望行号(和列号,如果有的话)准确指出大括号
{}
中的哪些“属性赋值”导致异常。所有这些都转换为临时(不可见)变量属性的赋值。只有在一切顺利的情况下,临时变量才会复制到您的
结果
值中


我也遇到过涉及对象初始值设定项的堆栈跟踪带来的不便。

是的,但在到达该行之前应该会爆炸。也许我不相信他的错误消息:)代码没有按原样编译。。。所以我假设它是从多个来源粘贴的hodge podge。是的,但它应该在到达那一行之前爆炸。也许我不相信他的错误消息:)代码没有按原样编译。。。所以我假设它是从多个来源粘贴的hodge podge。您是否仔细检查了代码,并看到它认为什么是空的?您的日志输出显示哪些字段的值?您是否100%确定错误的行号?您是否在发现错误后添加日志记录(这将更改您的行号?您使用的是最新版本吗?您是否仔细检查了代码并查看它认为为空的内容?您的日志输出显示哪些字段的值?您是否100%确定错误的行号?您是否在发现错误后添加日志记录(这会改变你的行号吗?你使用的是最新版本吗?同意,这种初始化会让调试变得比少数属性更糟糕。而且它很难看。好吧,我试过了,导致这一结果的行是result.SecondsToRespond=30;。我不知道为什么这意味着如果你评论这一行,不会出现异常抛出?否,如果我将其注释掉,就会从var result2=new OrderDataDriver()中得到一个异常;甚至在那之前。所以最后我通过重新启动visual studio解决了这个问题。我不知道会发生这样的问题。谢谢大家!同意,这种初始化使得调试对于一些属性以外的任何东西都很糟糕。而且很难看。好的,我尝试过,导致这个问题的行是result.SecondsToRespond=30;。我没有想法为什么这意味着如果你注释这一行,不会抛出异常?不,如果我注释掉它,我会从var result2=new OrderDataDriver()中得到一个异常,甚至在这之前。所以最后我通过重新启动visual studio解决了这个问题。我不知道会发生这样的问题。谢谢大家!