如果我有:
class Test
{
private Vector2 v;
public Vector2 Velocity
{
get { return v; }
set { v = value; }
}
}
然后:
Test t = new Test();
t.Velocity = new Vector2(2, 2);
t.Velocity.Normalize();
Console.WriteLine(t.Velocity); // here not normalized
Vector2 tmp = t.Velocity;
tmp.Normalize();
t.Velocity = tmp;
Console.WriteLine(t.Velocity); // here normalized
Console.Read();
为什么我直接尝试在Velocity属性上调用Normalize它没有规范化 并使用tmp Vector2它是?
P.S。 Vector2是一个结构:
public struct Vector2 : IEquatable<Vector2>
{
public float X;
public float Y;
...
public void Normalize() {...}
}
答案 0 :(得分:6)
我假设 不中的问题与.NET Framework
中的实际属性如何相关,但内部如何管理value types
。 NET Framework。
我使用了CAD内核,即使从提供的代码中看不清楚,我假设 Vector2
是struct
(通常是快速加速)分配/渲染),因此它是value type
当你Normalize(...)
一个值类型标准化它的副本时,这就是为什么在第二种情况下它起作用,导致首先你规范化复制, 后将其分配给原始值。
希望这有帮助。
答案 1 :(得分:5)
如果Vector2
是value type,则属性获取器将返回一个新副本,将Normalize()
应用于该副本不会影响原始副本。
换句话说,v
和t.Velocity
不是同一个对象,因此对一个对象的更改不会反映在另一个对象中。
如果Vector2
是reference type,您将获得正在寻找的行为。
答案 2 :(得分:4)
列出项目
我想在你的情况下Vector2
是一个值类型(struct)。
在这种情况下,在您的第一个示例中,您将获得v
属性的获取部分返回的Velocity
的副本,您将在副本上有效地调用Normalize
什么都不做,因为在调用Normalize之后副本超出了范围。
如果Vector2是一个引用类型(类),那么这可以按预期工作,而不必先创建一个新对象,然后使用Velocity
的set部分分配它。
请记住,可变结构是evil。如果你总是使你的结构不可变,你不应该遇到这样的问题。
答案 3 :(得分:0)
在不知道Vector2
的细节的情况下,它听起来像是一种价值类型。因此,您没有提及Velocity
,而是提供了它的副本。