And*_*ndy 9 c# heap stack properties value-type
我对堆栈和堆中发生的事情与类中的值类型属性相混淆.
到目前为止我的理解:
当您创建具有结构(值类型)的类时,如下所示:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
如果您创建一个类实例,如下所示:
Foo fooObj = new Foo();
Run Code Online (Sandbox Code Playgroud)
堆栈和堆将如下所示:

...将Bar结构嵌入堆中的Foo类中.这对我来说很有意义,但是当我们考虑在Foo对象中修改BarStruct类中的Number整数时,我开始松开它.例如:
Foo fooObj = new Foo();
fooObj.BarStruct.Number = 1;
Run Code Online (Sandbox Code Playgroud)
据我所知,这应该返回一个BarStruct的副本以存在于堆栈中,这意味着BarStruct成员的任何更改都不会传递给该对象,这就是上面最后一行给出错误的原因.
到目前为止这是对的吗?
如果是这样,我的问题是,如何做出这样的任务:
fooObj.BarStruct = new Bar(2);
Run Code Online (Sandbox Code Playgroud)
...有效并更改堆值?当然这只是改变堆栈上的值?此外,(by和by)我发现它很混乱,你可以在值类型上使用new.对我来说,new是在堆上进行分配(根据C++),并且对堆栈中的项目执行此操作感觉不自然.
所以只是为了重新迭代这个问题,我是否正确地假设当调用包含结构的属性时会发生什么,为什么你可以为副本分配一个新结构但是它仍然会改变堆上的引用?
真的希望这一切都有意义.
如果你需要澄清,请大喊大叫!
钽,
安迪.
Jon*_*eet 10
看看这个作业:
fooObj.BarStruct = new Bar(2);
Run Code Online (Sandbox Code Playgroud)
赋值不会改变堆栈上的值 - 它正在调用属性的setter.
换句话说,你的第一个任务相当于:
fooObj.get_BarStruct().Number = 1; // Bad
Run Code Online (Sandbox Code Playgroud)
第二个相当于:
fooObj.set_BarStruct(new Bar(2));
Run Code Online (Sandbox Code Playgroud)
这有帮助吗?
请注意,如果您将值类型设置为不可变,则有问题的赋值将成为非问题 - 事实上,这通常有帮助.可变值类型在C#中是一个非常糟糕的主意; 你可以忍受它们的麻烦.
就你对"新"的期望而言 - 基本上不要用C++思考.C#不是C++,如果你试图在C#中有效地编写C++,各种各样的事情(析构函数,泛型,构造期间的行为)会让你感到困惑."new"语句创建类型的新实例,无论是值类型还是引用类型.
| 归档时间: |
|
| 查看次数: |
975 次 |
| 最近记录: |