1

我创建了一个自定义结构和一个类。结构是 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,但是如何在无需编写构造函数的情况下克服这个问题,将至少一个点作为参数,即创建一个空路径。

4

3 回答 3

1

您有两个成员storedPointsStoredPoints并且不相关!

您应该明确写出 getterStoredPoints并让它 return storedPoints

(此外,您创建的结构是可变结构。许多人认为这是危险的。)

于 2013-06-06T14:04:20.170 回答
1

您的StoredPoints属性是单独的并且未初始化。您的意图可能是它将获取/设置您的私有storedPoints字段。修改获取/设置函数StoredPoints以获取/设置您的私有字段,您将解决您的问题。

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\。

一个与另一个无关。您可以有一个构造函数而不初始化您的列表。

还有一点要记住:拥有一个 nullStoredPoints属性实际上意味着什么不同于一个空StoredPoints属性吗?如果不是,那么安全并初始化StoredPoints为一个空列表。

于 2013-06-06T14:06:08.163 回答
1
public List<Point3D> StoredPoints { get; set; }

当您调用AddPoints时,您正在尝试访问尚未初始化的属性。在您使用该StoredPoints物业之前,您必须

StoredPoints = new List<Point3D>();
于 2013-06-06T14:09:26.090 回答