繁体   English   中英

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

[英]why does this raise a null object exception

我收到未设置为对象实例的Object引用。:OperatorAssembly: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; }
}

将复杂对象初始化更改为以下形式:

var result = new OrderDataDriver();
result.blablah = foor.bar;

然后,您将获得更好的错误消息,其中包含您尝试访问null对象的属性的确切行号。

这里是参考这种可爱模式的好地方,它使开发人员的生活更轻松http://en.wikipedia.org/wiki/Fail-fast

如果该属性为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已经被记录,因此应该早些捕获它们。

除非您有带有副作用的吸气剂。 那些纯属邪恶,所以要当心。 另一种可能性是另一个线程更改了一个值。 这甚至更难以证明。

当您使用对象初始化程序时,例如

result = new OrderDataDriver { OrderId = order.Id, Address = order.Location.Address, Lat = order.Location.Latitude, Lng = order.Location.Longitude, };

不要期望行号(如果有的话,还有列号)会准确指出括号{ }哪个“属性分配”会导致异常。 毕竟,这将转换为对临时(不可见)变量的属性的分配。 只有一切顺利,临时变量才会复制到您的result值中。

我还经历了涉及对象初始化程序的堆栈跟踪带来的不便。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM