3

如果我有:

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 它是?

PS Vector2 是一个结构:

public struct Vector2 : IEquatable<Vector2>
{
    public float X;
    public float Y;
    ...
    public void Normalize() {...}
}
4

4 回答 4

6

这个问题与实际如何管理属性无关.NET Framework而是如何value types在 .NET Framework 中管理。

我使用 CAD 内核,即使提供的代码不清楚,我认为Vector2是一个struct(通常是为了加快快速分配/渲染的速度),所以它是一个value type

当你Normalize(...)是一个值类型时,你规范化它的副本,这就是为什么在第二种情况下它起作用的原因,首先你规范化copy然后将它分配给原始值。

希望这可以帮助。

于 2012-06-19T10:01:04.910 回答
5

如果Vector2值类型,则属性 getter 将返回一个新副本,并且应用于Normalize()该副本不会影响原始副本。

换句话说,vandt.Velocity不是同一个对象,因此对一个对象所做的更改不会反映在另一个对象中。

如果Vector2引用类型,您将获得您正在寻找的行为。

于 2012-06-19T10:00:03.910 回答
4

项目清单

我猜你的情况Vector2是一个值类型(结构)。

在这种情况下,在您的第一个示例中,您将获得v由属性的 get 部分返回的副本,Velocity并且您将调用Normalize该副本,实际上什么都不做,因为在调用 Normalize 后副本超出了范围。

如果 Vector2 是一个引用类型(类),这将按您的预期工作,而不必先创建一个新对象,然后使用Velocity.

请记住,可变结构是邪恶的。如果你总是让你的结构不可变,你就不应该遇到这样的问题。

于 2012-06-19T09:59:48.123 回答
0

在不知道您的具体情况的情况下,Vector2它听起来像是一种值类型。因此,您获得的不是您的参考,Velocity而是它的副本。

于 2012-06-19T10:00:08.497 回答