gpt4 book ai didi

c# - C#中字段和属性之间的细微差别

转载 作者:太空宇宙 更新时间:2023-11-03 12:32:28 28 4
gpt4 key购买 nike

(这不是 What is the difference between a field and a property in C# 的副本 - 而是一个更微妙的问题)

我有一个不可变类 Camera(来自 this 光线追踪示例),它工作正常:

public class Camera
{
public Vector3D Pos;
public Vector3D Forward;
public Vector3D Up;
public Vector3D Right;

public Camera(Vector3D pos, Vector3D lookAt)
{
Pos = pos;
Forward = lookAt - pos;
Forward.Normalize();
Vector3D Down = new Vector3D(0, -1, 0);
Right = Vector3D.CrossProduct(Forward, Down);
Right.Normalize();
Right *= 1.5;
Up = Vector3D.CrossProduct(Forward, Right);
Up.Normalize();
Up *= 1.5;
}
}

由于这是一个不可变的类,我想将字段更改为只读属性,我在整个应用程序中都没有遇到任何问题,因此:

public Vector3D Pos { get; private set; } 
public Vector3D Forward { get; private set; }
public Vector3D Up { get; private set; }
public Vector3D Right { get; private set; }

其余代码未更改 - 但应用程序不再正常运行。经调查,Forward、Up 和 Right 的值不再标准化。 Normalize,在构造函数(上面)中调用了 3 次,是一个 void 方法。似乎在属性上而不是在字段上调用这样的方法(至少在构造函数中)不会导致属性的值被更新。看起来好像向量(一个结构)是通过引用而不是通过值传递的,如果这有意义的话。

我能找到让它工作的唯一方法是在设置属性值之前在构造函数中完成我的所有转换,如下所示:

public  Camera(Vector3D pos, Vector3D lookAt)
{
var forward = lookAt - pos;
forward.Normalize();
var down = new Vector3D(0, -1, 0);
var right = Vector3D.CrossProduct(forward, down);
right.Normalize();
right *= 1.5;
var up = Vector3D.CrossProduct(forward, right);
up.Normalize();
up *= 1.5;
Pos = pos;
Forward = forward;
Up = up;
Right = right;
}

谁能给我解释一下这里到底发生了什么?我知道属性和字段之间存在差异如果您在 get 或 set 中添加任何额外的行为,但我不是。

最佳答案

这是可变值类型的众多问题之一,也是应该完全避免它们的原因。

在您的第一个场景中:

public Vector3D Forward; 
Forward.Normalize();

存储在变量 Forward 中的 valueVector3D 本身的实例。因此,当您调用 Forward() 时,您正在改变存储在 Forward 中的值,一切都按预期进行。

但是,在下面的代码中:

private Vector3D forward;

public Vector3D Forward
{
get { return forward; }
private set { forward = value; }
}

Forward.Normalize();

Normalize 是在forward 字段中存储的值的副本 上调用的(请记住,C# 中的默认行为是传递参数按值(value))。因为值类型的变量值本身就是值类型实例,所以您所做的是改变一个副本,而不是存储在forward 中的值。

在您的情况下,该属性是自动生成的,但原理是相同的。自动生成的属性也有一个支持字段,编译器只是为您省去所有涉及的管道的麻烦。

关于c# - C#中字段和属性之间的细微差别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42221783/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com