簡體   English   中英

嘗試使用struct填充自定義類的空實例時出現NullReferenceException

[英]NullReferenceException when trying to populate an empty instance of a custom class with a struct

我創建了一個自定義結構和一個類。 結構是3D空間中的點:

public struct Point3D
{
    //fields
    private static Point3D center = new Point3D(0,0,0);

    //properties
    public int X { get; set; }
    public int Y { get; set; }
    public int Z { get; set; }
    public static Point3D Center { get { return center; } }

    //constructors
    public Point3D(int x, int y, int z) : this()
    {
        this.X = x;
        this.Y = y;
        this.Z = z;
    }

    public override string ToString() { return string.Format("({0}; {1}; {2})", this.X, this.Y, this.Z); }
}

並且自定義類是應該存儲點的路徑:

public class Path
{
    private List<Point3D> storedPoints = new List<Point3D>();

    public List<Point3D> StoredPoints { get; set; }

    public void AddPoint(Point3D point) { this.StoredPoints.Add(point); }

    public void DeletePointAt(int index) { this.StoredPoints.RemoveAt(index); }

    public void ClearPath() { this.StoredPoints.Clear(); }

    public override string ToString()
    {
        StringBuilder sb = new StringBuilder();
        foreach (var item in this.StoredPoints)
        {
            sb.Append(item);
            sb.Append(System.Environment.NewLine);
        }
        return sb.ToString();
    }
}

我沒有為路徑類創建構造函數,因為我總是希望在其中有一個帶有空列表List \\的實例。 但是,當我運行程序時,我得到NullReferenceException。 這是主要方法的代碼:

    static void Main(string[] args)
    {
        Point3D point1 = new Point3D(-2, -4, -10);
        Point3D point2 = new Point3D(6, 7, 8);
        Path path1 = new Path();
        path1.AddPoint(point1);
        path1.AddPoint(point2);
        path1.AddPoint(new Point3D(2, 4, 6));
        path1.AddPoint(new Point3D(-9, 12, 6));
        Console.WriteLine(path1);
    }

當我嘗試添加第一個點時,我收到錯誤。 在調試器中,我看到Path對象在添加第一個點之前的值為null,但是如何在不必編寫構造函數的情況下克服此問題,將至少一個參數作為參數,即創建一個空路徑。

你有兩個成員storedPointsStoredPoints不相關!

你應該明確地寫出StoredPoints的getter並讓它返回storedPoints

(此外,您創建的結構是一個可變結構。許多人認為這很危險。)

您的StoredPoints屬性是單獨的,未初始化。 您的意圖可能是它將獲取/設置您的私有storedPoints字段。 修改StoredPoints的get / set函數以獲取/設置您的私有字段,您將解決您的問題。

public List<Point3D> StoredPoints 
{ 
  get
  {
    return storedPoints;
  }
}

編輯:

如果刪除storedPoints字段,但仍不需要構造函數,則可以執行以下操作:

public void AddPoint(Point3D point) 
{ 
  if (this.StoredPoints == null)
    this.StoredPoints = new List<Point3D>();
  this.StoredPoints.Add(point); 
}

這稱為延遲初始化。 但是,上述實現不是線程安全的。 如果您保證是單線程的,那么應該沒問題。 您可能希望在StoredPoints其他修改器中進行類似的初始化。 每當從類外部直接訪問時,您還需要檢查StoredPoints是否為null。

編輯:

我沒有為路徑類創建構造函數,因為我總是希望在其中有一個帶有空列表List \\的實例。

一個與另一個無關。 您可以擁有構造函數而不是初始化列表。

要記住的其他事項:確實有一個空的StoredPoints屬性實際上意味着什么不同於一個空的StoredPoints屬性? 如果沒有,那么安全並將StoredPoints初始化為空列表。

public List<Point3D> StoredPoints { get; set; }

當您調用AddPoints ,您正在嘗試訪問尚未初始化的屬性。 在使用StoredPoints屬性之前,您必須這樣做

StoredPoints = new List<Point3D>();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM