我正在开发一个简单的应用程序,我有点困惑.我有一个简单struct Point的int x和int y.而我用它Line
public class Line : Shape {
public Line() {
PointA = new Point(x: 0, y: 0);
PointB = new Point(x: 0, y: 0);
}
public Point PointA { get; set; }
public Point PointB { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
在某个地方
var line = new Line();
line.PointB = new Point(x: 4, y: 2);
Console.WriteLine($"Line start at {line.PointA.GetX()}:{line.PointA.GetY()}; end at {line.PointB.GetX()}:{line.PointB.GetY()}");
for (int i = 0; i < 10; i++) {
line.PointB.IncrementX();
line.PointB.IncrementY();
}
Console.WriteLine($"Line start at {line.PointA.GetX()}:{line.PointA.GetY()}; end at {line.PointB.GetX()}:{line.PointB.GetY()}");
Run Code Online (Sandbox Code Playgroud)
这里需要增加x和y的Point,但结果并没有改变:
行开始于0:0; 结束于4:2
线开始于0:0; 以4:2结束
我做错了什么?这看起来很奇怪.是否有一些特定的规则要struct在C#中使用.我知道这是一种价值类型,但我认为这对Point有利.所有示例都struct用于Point.请帮忙?
点:
public struct Point {
private int _x;
private int _y;
public Point(int x, int y)
: this() {
_x = x;
_y = y;
}
public void IncrementX() {
_x++;
}
public void IncrementY() {
_y++;
}
public int GetX() {
return _x;
}
public int GetY() {
return _y;
}
}
Run Code Online (Sandbox Code Playgroud)
Struct是一种值类型.它通过值传递(即通过创建所有字段的副本)而不是传递对struct实例的引用.所以,当你这样做
line.PointB.IncrementX()
Run Code Online (Sandbox Code Playgroud)
当您调用PropertyB的getter时,它将返回存储在PropertyB支持字段中的Point 副本.然后你在副本上调用增量.因此原始价值将保持不变.
延伸阅读:值类型和引用类型,尤其是不同诱变只读的Structs其说
可变值类型是邪恶的.尝试始终使值类型不可变.
如果你想实际移动线点,你可以做什么?
将点类型更改为class.然后它将通过引用传递,并且所有方法将在您存储的原始点上调用Line.
将新(修改的)点实例分配给行
即你应该存储副本,更改它并分配回来
var point = line.PointB; // get copy
point.IncrementX(); // mutate copy
point.IncrementY();
line.PointB = point; // assign copy of copy
Run Code Online (Sandbox Code Playgroud)
您还可以使Point结构不可变(对值类型可以做的最好的事情):
public struct Point
{
public Point(int x, int y)
{
X = x;
Y = y;
}
public int X { get; }
public int Y { get; }
public Point IncrementX() => new Point(X + 1, Y);
public Point IncrementY() => new Point(X, Y + 1);
public Point Move(int dx, int dy) => new Point(X + dx, Y + dy);
}
Run Code Online (Sandbox Code Playgroud)
现在改变位置看起来像
line.PointB = line.PointB.Move(1, 1);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
100 次 |
| 最近记录: |