C#属性如何真正起作用?

时间:2012-06-19 09:56:01

标签: c# properties

如果我有:

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() {...}
}

4 个答案:

答案 0 :(得分:6)

假设 中的问题与.NET Framework中的实际属性如何相关,但内部如何管理value types。 NET Framework。

我使用了CAD内核,即使从提供的代码中看不清楚,我假设 Vector2struct(通常是快速加速)分配/渲染),因此它是value type

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

希望这有帮助。

答案 1 :(得分:5)

如果Vector2value type,则属性获取器将返回一个新副本,将Normalize()应用于该副本不会影响原始副本。

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

如果Vector2reference type,您将获得正在寻找的行为。

答案 2 :(得分:4)

列出项目

我想在你的情况下Vector2是一个值类型(struct)。

在这种情况下,在您的第一个示例中,您将获得v属性的获取部分返回的Velocity的副本,您将在副本上有效地调用Normalize什么都不做,因为在调用Normalize之后副本超出了范围。

如果Vector2是一个引用类型(类),那么这可以按预期工作,而不必先创建一个新对象,然后使用Velocity的set部分分配它。

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

答案 3 :(得分:0)

在不知道Vector2的细节的情况下,它听起来像是一种价值类型。因此,您没有提及Velocity,而是提供了它的副本。