【问题标题】:Assigning a variable of a struct that contains an instance of a class to another variable将包含类实例的结构的变量分配给另一个变量
【发布时间】:2011-06-26 22:02:19
【问题描述】:

在我的理解中,将一个结构的变量分配给另一个相同类型的变量会产生一个副本。但是这条规则似乎被打破了,如下图所示。你能解释一下为什么会这样吗?

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

【问题讨论】:

  • (此评论将被删除)对于回答我问题的人,我稍后会回来投票和绿色复选标记。对不起。

标签: c# class struct value-type reference-type


【解决方案1】:

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

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

复制结构不会导致克隆。

事实上,在结构中放置引用是一个坏主意,应该避免。 一个例外是不可变引用对象(例如字符串),它们可以“安全”地放置在结构中,因为它们不能被修改,但是您仍然会丢失内存中的局部性。

请记住,值类型在其定义范围内本地存储,引用类型始终存储在堆上,而引用则在其定义范围内本地存储。

【讨论】:

  • +1 为您提供答案和建议,以避免在结构中引用字段。
  • “事实上,在结构中放置引用是个坏主意,应该避免。” - 这是一般情况吗?在 struct 中有一个字符串(这是一个引用类型)怎么样?
  • 字符串是不可变的,这解决了复制问题。但是,您仍然会丢失局部性。将编辑澄清。
【解决方案2】:

补充其他人所说的: 如果您需要说服自己 p1.inner 和 p2.inner 确实指向同一个类实例,您可以运行如下代码:

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

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

【讨论】:

    【解决方案3】:

    P1P2 都指向Inner 类型的一个对象... 这就是为什么值是相同的......

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

    现在尝试使用如下代码:

    
    ...
     p2 = p1.Clone();
    

    【讨论】:

      猜你喜欢
      • 2018-03-29
      • 2021-04-04
      • 1970-01-01
      • 2018-05-07
      • 2022-11-27
      • 2014-08-20
      • 2021-05-24
      • 1970-01-01
      • 2015-06-09
      相关资源
      最近更新 更多