2

据我了解,将结构的变量分配给相同类型的另一个变量将进行复制。但是这条规则似乎被打破了,如下图所示。你能解释一下为什么会这样吗?

在此处输入图像描述

using System;

namespace ReferenceInValue
{
    class Inner
    {
        public int data;
        public Inner(int data) { this.data = data; }
    }

    struct Outer
    {
        public Inner inner;
        public Outer(int data) { this.inner = new Inner(data); }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Outer p1 = new Outer(1);
            Outer p2 = p1;
            Console.WriteLine("p1:{0}, p2:{1}", p1.inner.data, p2.inner.data);


            p1.inner.data = 2;
            Console.WriteLine("p1:{0}, p2:{1}", p1.inner.data, p2.inner.data);


            p2.inner.data = 3;
            Console.WriteLine("p1:{0}, p2:{1}", p1.inner.data, p2.inner.data);

            Console.ReadKey();
        }
    }
}
4

3 回答 3

4

您在主题中回答了您的问题。

你的结构包含一个引用,当结构被复制时,它被复制为一块内存,包括引用(不是被引用的对象),就像引用是一个整数或另一个原语一样。

复制结构不会导致克隆。

In fact, placing a reference in a structure is a bad idea and should be avoided. An exception to this is immutable reference objects (such as strings), which are "safe" to place in structures, since they can not be modified, however you will still loose locality in memory.

Remember, value types are stored locally in the scope of their definition, reference types are always stored on heap and a reference is stored locally in the scope of their definition.

于 2011-06-26T22:10:46.913 回答
2

Adding to what the others have said : If you need to convince yourself that p1.inner and p2.inner are indeed pointing to the same class instance, you can run code like this :

Console.WriteLine("ReferenceEquals:{0}", object.ReferenceEquals(p1.inner, p2.inner));

如果你在“Outer p2 = p1;”行之后的任何时候运行它,它总是会写成:“ReferenceEquals:True”。

于 2011-06-27T06:15:11.813 回答
0

P1 and P2 both are pointing to one object of type Inner... That's why values are the same...


struct Outer
{
   public Inner inner;
   public Outer(int data) { this.inner = new Inner(data); }

   public Clone() { return new Outer(this.inner.data); }
}

now try using the code like so:


...
 p2 = p1.Clone();
于 2011-06-26T22:25:35.723 回答