简体   繁体   English

从属性返回值类型

[英]Returning a value type from a property

I'm getting confused with what happens on the stack and heap in respect to value type properties in classes.关于类中的值类型属性,我对堆栈和堆上发生的事情感到困惑。

My understanding so far:到目前为止我的理解:

When you create a class with a structure (value type) like this:当您创建具有如下结构(值类型)的类时:

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;
  }
}

If you create a class instance like so:如果你像这样创建一个类实例:

Foo fooObj = new Foo();

The stack and heap will look like this:堆栈和堆将如下所示:

https://i962.photobucket.com/albums/ae105/acardy/stackheap-1.jpg(https://i962.photobucket.com/albums/ae105/acardy/stackheap-1.jpg)

...where the Bar structure is embeded in the Foo class in the heap. ...其中 Bar 结构嵌入在堆中的 Foo 类中。 This makes sense to me, but I start to loose it when we consider modifying the Number integer in the BarStruct class, within the Foo Object.这对我来说很有意义,但是当我们考虑在 Foo 对象中修改 BarStruct 类中的 Number 整数时,我开始失去它。 For example:例如:

Foo fooObj = new Foo();
fooObj.BarStruct.Number = 1;

As I understand, this should be returning a copy of BarStruct to live on the stack, which means that any changes of a member of BarStruct would not be carried through to the object, which is why the last line above gives an error.据我了解,这应该返回一个 BarStruct 的副本以存在于堆栈中,这意味着 BarStruct 成员的任何更改都不会传递到对象,这就是上面最后一行给出错误的原因。

Is this right so far?到目前为止,这是正确的吗?

If so, my question is, how come an assignment such as this:如果是这样,我的问题是,怎么会有这样的作业:

fooObj.BarStruct = new Bar(2);

...is valid and changes the heap value? ...有效并更改堆值? Surely this is just changing the value on the stack??当然这只是改变堆栈上的值?? Also, (by and by) I find it so confusing that you are able to use new on a value type.此外,(渐渐地)我发现它非常令人困惑,以至于您可以在值类型上使用 new 。 To me, new is for allocatting on the heap (as per C++) and feels unnatural to be doing this for items on the stack.对我来说,new 用于在堆上分配(按照 C++),并且为堆栈上的项目执行此操作感觉不自然。

So just to re-iterate the question, Am I correct in my assumption of what happens when a property containing a structure is called and why can you assign a new structure to a copy and yet it still changes the reference on the heap?所以只是重申这个问题,我假设当包含结构的属性被调用时会发生什么,为什么你可以将一个新结构分配给一个副本,但它仍然改变堆上的引用?

Really hope this all make sense.真的希望这一切都有意义。

Yell if you need clarification!如果您需要澄清,请大喊大叫!

Ta,塔,

Andy.安迪。

Looking at this assignment:看看这个作业:

fooObj.BarStruct = new Bar(2);

The assignment isn't changing the value on the stack - it's calling the setter for the property.赋值不会改变堆栈上的值 - 它正在调用属性的setter

In other words, whereas your first assignment is equivalent to:换句话说,而您的第一个作业相当于:

fooObj.get_BarStruct().Number = 1; // Bad

the second is equivalent to:第二个相当于:

fooObj.set_BarStruct(new Bar(2));

Does that help?这有帮助吗?

Note that the problematic assignment becomes a non-issue if you make your value type immutable to start with - which helps in general, in fact.请注意,如果您使值类型一开始不可变,则有问题的分配将成为非问题 - 事实上,这通常有帮助。 Mutable value types are a really bad idea in C#;可变值类型在 C# 中是一个非常糟糕的主意; you can get into no end of trouble with them.你可能会遇到无穷无尽的麻烦。

In terms of your expectations of "new" - try not to think in C++, basically.就您对“新”的期望而言 - 基本上尽量不要用 C++ 思考。 C# isn't C++, and various things (destructors, generics, behaviour during construction) will confuse you if you try to effectively write C++ in C#. C# 不是 C++,如果您尝试在 C# 中有效地编写 C++,那么各种事情(析构函数、泛型、构造期间的行为)会让您感到困惑。 A "new" statement creates a new instance of a type, whether that's a value type or a reference type. “new”语句创建一个类型的新实例,无论是值类型还是引用类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM