2012-11-28 44 views
3

這行(C#)代碼可空屬性上.HasValue

if (!currentLap.S1.HasValue) 

是給我

System.NullReferenceException投擲的NullReferenceException:未設置爲一個對象的實例對象引用。

提供我敢肯定,currentLap變量被實例化(因爲它是被使用過了幾行,它是一個局部變量),它具有以下特性:

private double? _s1; 

[DefaultValue(null)] 
[JsonConverter(typeof(ShortDoubleConverter))] 
public double? S1 
{ 
    get { return _s1; } 
    set { _s1 = value; } 
} 

它怎麼能扔的NullReferenceException?它可能與發佈模式的優化有關嗎?

感謝, 斯特沃

編輯:

這裏充滿了法碼。

public void Update(DriverData driverData) 
    { 
     LapInfo currentLap = this.CurrentLap; 

     if (currentLap != null && 
     this.LastDriverData != null && 
     driverData.TotalLaps != this.LastDriverData.TotalLaps && 
     driverData.InPits && 
     driverData.Speed < 10 && 
     !this.LastDriverData.InPits) 
     { 
      currentLap.Escaped = true; 
     }  

     this.LastDriverData = driverData; 

     if ((currentLap == null || currentLap.Lap != driverData.LapNumber) && 
      !this.Laps.TryGetValue(driverData.LapNumber, out currentLap)) 
     { 
      currentLap = new LapInfo() { Lap = driverData.LapNumber, Parent = this, Class = driverData.Class }; 
      this.Laps.Add(driverData.LapNumber, currentLap); 

      int lapsCount = 0, completedDriverLaps = 0, cleanLaps = 0; 
      this.TotalLaps = driverData.TotalLaps; 

      //if it's not the first lap 
      if (driverData.TotalLaps > 0) 
      { 
       //previous lap 
       if (this.CurrentLap == null || !this.CurrentLap.Escaped) 
       { 
        this.CompletedLaps++; 

        if (this.CurrentLap == null || !this.CurrentLap.MaxIncident.HasValue) 
         this.CleanLaps++; 
       } 
      } 

      foreach (DriverLapsInfo laps in this.Parent.LapsByVehicle.Values) 
      { 
       lapsCount += laps.TotalLaps; 
       completedDriverLaps += laps.CompletedLaps; 
       cleanLaps += laps.CleanLaps; 
      } 

      this.Parent.Parent.SetLapsCount(driverData, lapsCount, driverData.Class, completedDriverLaps, cleanLaps); 
     } 

     this.CurrentLap = currentLap; 

     //add incidents 
     if (driverData.Incidents != null) 
     { 
      foreach (IncidentScore incident in driverData.Incidents) 
      { 
       this.CurrentLap.MaxIncident = Math.Max(this.CurrentLap.MaxIncident ?? 0, incident.Strength); 
       this.CurrentLap.Incidents++; 
       this.Incidents++; 
      }     
     } 

     LapInfo previousLap = null; 
     if ((this.PreviousLap == null || this.PreviousLap.Lap != driverData.TotalLaps) && 
      this.Laps.TryGetValue(driverData.TotalLaps, out previousLap)) 
     { 
      this.PreviousLap = previousLap; 

      if (!this.PreviousLap.Date.HasValue) 
      { 
       this.PreviousLap.Date = DateTime.UtcNow; 
      } 
     } 

     if (currentLap.Position == 0) 
      currentLap.Position = driverData.Position; 

     if (driverData.CurrentS1 > 0) 
     {     
      **if (!currentLap.S1.HasValue)** 
      { 
       this.UpdateBestS1(driverData.BestS1); 
       this.Parent.Parent.UpdateBestS1(driverData.BestS1, driverData.UniqueName); 
       currentLap.UpdateS1(driverData.CurrentS1, driverData); 

       //reset the best split set at the finish line 
       if (this.PreviousLap != null && this.PreviousLap.SplitBest < 0) 
        this.PreviousLap.SplitBest = 0; 
      } 

      if (driverData.CurrentS2.HasValue && driverData.CurrentS1.HasValue && !currentLap.S2.HasValue) 
      { 
       double s2 = driverData.CurrentS2.Value - driverData.CurrentS1.Value;  
       this.UpdateBestS2(s2); 
       this.Parent.Parent.UpdateBestS2(s2, driverData.UniqueName); 
       currentLap.UpdateS2(s2, driverData);       
      } 
     }    

     if (this.PreviousLap != null) 
     { 
      if (driverData.LastLap > 0) 
      { 
       if (!this.PreviousLap.S3.HasValue && driverData.LastS2.HasValue) 
       { 
        double s3 = driverData.LastLap.Value - driverData.LastS2.Value; 
        this.UpdateBestS3(s3); 
        this.Parent.Parent.UpdateBestS3(s3, driverData.UniqueName);       
        this.PreviousLap.UpdateS3(s3, driverData); 
       } 

       if (!this.PreviousLap.LapTime.HasValue) 
       { 
        double? bestLap = this.Parent.Parent.BestLap; 
        this.PreviousLap.UpdateLapTime(driverData, 0); 
        this.Parent.Parent.UpdateBestLap(this.PreviousLap, driverData.BestLap, driverData); 
        this.UpdateBestLap(driverData.BestLap, this.PreviousLap); 
        this.PreviousLap.UpdateLapTime(driverData, bestLap); 
       } 
      } 

      else 
      { 
       if (this.PreviousLap.SplitBest.HasValue) 
        this.PreviousLap.UpdateBestSplit(); 
       if (this.PreviousLap.SplitSelf.HasValue) 
        this.PreviousLap.UpdateSelfSplit(); 
      } 
     } 

     if (driverData.InPits) 
     { 
      switch (driverData.Sector) 
      { 
       case Sectors.Sector1: 
        if (previousLap != null) 
         previousLap.InPits = true; 
        break; 
       case Sectors.Sector3: 
        currentLap.InPits = true; 
        break; 
      } 
     } 

     //lap to speed 
     if (currentLap.TopSpeed < driverData.Speed) 
     { 
      driverData.TopSpeedLap = driverData.Speed; 
      currentLap.UpdateTopSpeed(driverData.Speed); 
     } 
     else 
      driverData.TopSpeedLap = currentLap.TopSpeed; 

     //overall top speed 
     if (this.TopSpeed < driverData.Speed) 
     { 
      driverData.TopSpeed = driverData.Speed; 
      this.TopSpeed = driverData.Speed; 
      this.Parent.Parent.UpdateTopSpeed(this.TopSpeed, driverData); 
     } 

     else 
      driverData.TopSpeed = this.TopSpeed; 

    } 

地球上沒有辦法讓代碼可以使它到達那條線並且currentLap beeing null。

還是我瘋了? :)

+5

_s1在哪裏/如何聲明,你真的很確定 - currentLap不可能爲null嗎? –

+1

嘗試:if(currentLap!= null &&!currentLap.S1.HasValue) 這將檢查currentLap是否爲空。 –

+6

我強烈懷疑'currentLap' *是* null。嘗試創建一個簡短但完整的程序來演示問題。 –

回答

10

.HasValue不會拋出如果可空引用爲空,但a.b.HasValue如果a將爲空。 我懷疑currentLap == null。我知道你說你確定currentLap不是null,但我認爲這是最可能的解釋。你能發佈更多的代碼嗎?

更新:

感謝張貼你的代碼。

這並不拋出:

void Main() { 
    var f = new Foo(); 

    Console.WriteLine (f.S1); 
    Console.WriteLine (f.S1.HasValue); 
} 

class Foo { 
    private double? _s1 = null; 

    public double? S1 { 
     get { return _s1; } 
     set { _s1 = value; } 
    } 
} 

你能嘗試創建一個最小的再現? (展示此問題的最小代碼)

+0

發佈了代碼。即使沒有運行它,你可以知道它不能爲空 – user1275154

+2

你怎麼知道它不能爲空?我沒有看到它。 – recursive

2

也許看看上一行代碼:) - 調試器經常在實際拋出NullReferenceException之後突出顯示下一行。

+0

這完全發生在我身上。 –