[英]Returning a value type from a property
关于类中的值类型属性,我对堆栈和堆上发生的事情感到困惑。
到目前为止我的理解:
当您创建具有如下结构(值类型)的类时:
class Foo
{
private Bar _BarStruct;
public Bar BarStruct
{
get {return _BarStruct; }
set {_BarStruct = value; }
}
}
private struct Bar
{
public int Number;
Bar()
{
Number = 1;
}
Bar(int i)
{
Number = i;
}
}
如果你像这样创建一个类实例:
Foo fooObj = new Foo();
堆栈和堆将如下所示:
...其中 Bar 结构嵌入在堆中的 Foo 类中。 这对我来说很有意义,但是当我们考虑在 Foo 对象中修改 BarStruct 类中的 Number 整数时,我开始失去它。 例如:
Foo fooObj = new Foo();
fooObj.BarStruct.Number = 1;
据我了解,这应该返回一个 BarStruct 的副本以存在于堆栈中,这意味着 BarStruct 成员的任何更改都不会传递到对象,这就是上面最后一行给出错误的原因。
到目前为止,这是正确的吗?
如果是这样,我的问题是,怎么会有这样的作业:
fooObj.BarStruct = new Bar(2);
...有效并更改堆值? 当然这只是改变堆栈上的值?? 此外,(渐渐地)我发现它非常令人困惑,以至于您可以在值类型上使用 new 。 对我来说,new 用于在堆上分配(按照 C++),并且为堆栈上的项目执行此操作感觉不自然。
所以只是重申这个问题,我假设当包含结构的属性被调用时会发生什么,为什么你可以将一个新结构分配给一个副本,但它仍然改变堆上的引用?
真的希望这一切都有意义。
如果您需要澄清,请大喊大叫!
塔,
安迪。
看看这个作业:
fooObj.BarStruct = new Bar(2);
赋值不会改变堆栈上的值 - 它正在调用属性的setter 。
换句话说,而您的第一个作业相当于:
fooObj.get_BarStruct().Number = 1; // Bad
第二个相当于:
fooObj.set_BarStruct(new Bar(2));
这有帮助吗?
请注意,如果您使值类型一开始不可变,则有问题的分配将成为非问题 - 事实上,这通常有帮助。 可变值类型在 C# 中是一个非常糟糕的主意; 你可能会遇到无穷无尽的麻烦。
就您对“新”的期望而言 - 基本上尽量不要用 C++ 思考。 C# 不是 C++,如果您尝试在 C# 中有效地编写 C++,那么各种事情(析构函数、泛型、构造期间的行为)会让您感到困惑。 “new”语句创建一个类型的新实例,无论是值类型还是引用类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.