我是C#的新手。我来自Java世界。所以我对以下代码感到困惑:
class A
{
private PointF point;
public A(PointF point)
{
this.point = point;
}
public PointF Position
{
get { return point; }
}
}
我想更改position属性的X坐标,所以我执行:
A a = new A(new PointF(1,2));
PointF p = a.Position;
p.X = 100;
Console.WriteLine(a.Position.X); // <--- I have 1 here!
我想知道为什么输出不是 100 ?据我了解,我已收到有关职位属性的私人领域的参考资料。我是对的吗?
我可以在不添加set-property的情况下更改属性,并使用新的 PointF 对象传播位置吗?
答案 0 :(得分:6)
没有; PointF
是struct
,因此它具有复制语义而不是对象;一旦你获得它 - 它是一个单独的和孤立的副本(除非你使用像ref
/ out
这样的东西,这是......更微妙)。在您的示例中,实际上会多次复制该结构。
顺便说一句,这样做的结果是拥有可变结构实际上是一个非常糟糕的主意 - 所以在大多数情况下你应该避免你可以说的场景:
p.X = 100;
因为这会导致更多的混乱而不是它有所帮助。特别是以下内容完全无效:
a.Position.X = 100; // won't even compile
(这里编译发现您正在更改仅在突变期间存在的结构的副本,这意味着您的更改无处,并且几乎肯定是一个错误)
答案 1 :(得分:2)
PointF
是一个结构。在.Net Framework结构中 valueTypes 。因此,您的示例将始终打印出来。
你在课堂上使用它并不重要。每次为值类型的变量赋值时,将复制值。
答案 2 :(得分:2)
PointF
是具有所有后果的值类型。
如果要更改属性中PointF
值的唯一“X”属性,则需要将值复制到变量中,更改“X”属性并设置更改的属性值。
var cls = new A();
var point = cls.Point;
point.X = 15;
cls.Point = point;
答案 3 :(得分:2)
在C#中有两种类型的变量 - 值类型和引用类型。分配值类型时,将复制它们 - 对于引用类型,将复制引用。
Point
是一种值类型(struct
),并且在分配时会复制。所以:
PointF p = a.Position;
p
是a.Position
的副本,完全独立于此。所以:
p.X = 100;
修改X
上p
的值,保持a.Position.X
不变。
答案 4 :(得分:0)
你需要使用保存的单词out(function)和ref(发送到函数时)通过引用传递参数
答案 5 :(得分:0)
我想知道为什么编译器不会给你一个警告。 这里发生的是你没有返回一个PointF引用,它可能是一个值类型,实际上你返回一个副本。然后修改该副本X属性。当然这不行。
答案 6 :(得分:0)
在您的示例中,p
和a
是两个不同的对象,因此更改前者不会影响后者。
答案 7 :(得分:0)
在C#中,您拥有properties
class A
{
public PointF Position {get;set;}
public A(PointF point)
{
this.Position = point;
}
}
A a = new A(new PointF(1,2));
a.Position.X = 100
Console.WriteLine(a.Position.X);