另一个 class 中的列表项在作为传递实例移除时消失
List item in another class disappears when removing as passed instance
我现在有点紧张。
我将 List 传递给另一个 class 的方法,在那个 class 中我使用了不同的变量名(封装)。但这里是:
当我从方法中的列表中删除一个项目时,该项目也会在另一个变量中消失!
对我做错了什么有什么建议吗?
这里是代码片段:
public partial class Form1 : Form
{
List<Vector> polygonPoints = new List<Vector>();
private void panel1_Paint(object sender, PaintEventArgs e)
{
// Create Convex Hull of polygon Set
QuickHull qh = new QuickHull();
// here I pass the list to a method in the class QuickHull
// here polygonPoints.Count = 5
List<Vector> hullOfPoints = qh.quickHull(polygonPoints);
// at this point I get polygonPoints.Count = 3
...
}
}
不同 class QuickHull:
class QuickHull
{
public List<Vector> quickHull(List<Vector> points)
{
List<Vector> convexHull = new List<Vector>();
...
Vector A = points[minPoint];
Vector B = points[maxPoint];
convexHull.Add(A);
convexHull.Add(B);
// at this point 'polygonPoints' also looses these items
points.Remove(A);
points.Remove(B);
...
}
}
我真的不知道该怎么办,因为它一直在工作,但时不时地就不再工作了。
我非常感谢每一个建议。
提前致谢。
您看到的是预期的行为。
A List<T>
是引用类型,因此当您将它传递给方法时,它是对传递的列表的引用。
使用不同的变量名称不会使其成为新列表。它仍然是您引用的同一个列表。
如果您想要列表的本地副本,您需要创建一个新列表并将项目复制到其中。您可以为此使用列表构造函数:
List<Vector> local = new List<Vector>(points);
您还可以更改发送到方法中的类型:
public List<Vector> quickHull(IEnumerable<Vector> points)
通过使用 IEnumerable<T>
接口而不是 List<T>
class,您将使用限制为仅枚举列表。您仍然可以将列表发送到方法中,但您不能错误地更改列表,您仍然可以使用它来创建本地副本。
当您将 List<T>
传递给方法时,您传递的值包含对该列表的引用。这意味着您在方法中接受的参数 points
指向您在调用链中较高位置实例化的同一个列表。
如果您想传递对单独列表的引用,则需要创建一个新列表:
List<Vector> hullOfPoints = qh.quickHull(polygonPoints.ToList());
您可以在 "Passing Reference-Type Parameters" 中阅读更多相关信息:
A variable of a reference type does not contain its data directly; it
contains a reference to its data. When you pass a reference-type
parameter by value, it is possible to change the data pointed to by
the reference, such as the value of a class member. However, you
cannot change the value of the reference itself;
您的问题是您传递了一个“reference”类型然后更改它。相反,您可以创建一个新列表(点)以避免修改先前的输入列表(多边形点)。
我现在有点紧张。 我将 List 传递给另一个 class 的方法,在那个 class 中我使用了不同的变量名(封装)。但这里是: 当我从方法中的列表中删除一个项目时,该项目也会在另一个变量中消失!
对我做错了什么有什么建议吗?
这里是代码片段:
public partial class Form1 : Form
{
List<Vector> polygonPoints = new List<Vector>();
private void panel1_Paint(object sender, PaintEventArgs e)
{
// Create Convex Hull of polygon Set
QuickHull qh = new QuickHull();
// here I pass the list to a method in the class QuickHull
// here polygonPoints.Count = 5
List<Vector> hullOfPoints = qh.quickHull(polygonPoints);
// at this point I get polygonPoints.Count = 3
...
}
}
不同 class QuickHull:
class QuickHull
{
public List<Vector> quickHull(List<Vector> points)
{
List<Vector> convexHull = new List<Vector>();
...
Vector A = points[minPoint];
Vector B = points[maxPoint];
convexHull.Add(A);
convexHull.Add(B);
// at this point 'polygonPoints' also looses these items
points.Remove(A);
points.Remove(B);
...
}
}
我真的不知道该怎么办,因为它一直在工作,但时不时地就不再工作了。
我非常感谢每一个建议。
提前致谢。
您看到的是预期的行为。
A List<T>
是引用类型,因此当您将它传递给方法时,它是对传递的列表的引用。
使用不同的变量名称不会使其成为新列表。它仍然是您引用的同一个列表。
如果您想要列表的本地副本,您需要创建一个新列表并将项目复制到其中。您可以为此使用列表构造函数:
List<Vector> local = new List<Vector>(points);
您还可以更改发送到方法中的类型:
public List<Vector> quickHull(IEnumerable<Vector> points)
通过使用 IEnumerable<T>
接口而不是 List<T>
class,您将使用限制为仅枚举列表。您仍然可以将列表发送到方法中,但您不能错误地更改列表,您仍然可以使用它来创建本地副本。
当您将 List<T>
传递给方法时,您传递的值包含对该列表的引用。这意味着您在方法中接受的参数 points
指向您在调用链中较高位置实例化的同一个列表。
如果您想传递对单独列表的引用,则需要创建一个新列表:
List<Vector> hullOfPoints = qh.quickHull(polygonPoints.ToList());
您可以在 "Passing Reference-Type Parameters" 中阅读更多相关信息:
A variable of a reference type does not contain its data directly; it contains a reference to its data. When you pass a reference-type parameter by value, it is possible to change the data pointed to by the reference, such as the value of a class member. However, you cannot change the value of the reference itself;
您的问题是您传递了一个“reference”类型然后更改它。相反,您可以创建一个新列表(点)以避免修改先前的输入列表(多边形点)。