传播未加框变量的变化

时间:2014-06-07 14:09:12

标签: c#

我做了一个小实验,看看改变一个未加框的变量是否会传播对原始源所做的更改,并根据我使用的类型得到两个完全不同的结果。我主要想知道WPF数据绑定应用程序,我绑定到object,强制转换,并希望原始更新其UI。

我的结果如下。

  1. 简单类型似乎在解除拳击后失去对原始来源的引用。
  2. 自定义类型似乎保留了他们的参考。
  3. 在我希望在更改未装箱的绑定数据上下文后我的WPF UI自我更新的情况下,我似乎没有什么可担心的;然而,不知道为什么只有复杂的物体才会发生这种情况让我感到担忧。我不希望我的UI在我不知道的罕见或奇怪的场合失败。任何人都可以解释那里机械地发生了什么?

    class Program
    {
        //simple types
        private static object sbox1;
        private static object sbox2;
    
        private static int svalue1 = 10;
        private static int svalue2 = 15;
    
        //custom types
        private static MyType cvalue1;
        private static MyType cvalue2;
    
        private static object cbox1;
        private static object cbox2;
    
        static void Main(string[] args)
        {
            //Box up the values
            sbox1 = svalue1;
            sbox2 = svalue2;
    
            //unbox the values to local var
            var sunboxed1 = (int)sbox1;
            var sunboxed2 = (int)sbox2;
    
            //change the values in the new unboxed vars
            sunboxed1 = -10;
            sunboxed2 = -15;
    
            //check unboxed values and check original value variables
            Console.WriteLine("unboxed1 = " + sunboxed1);
            Console.WriteLine("unboxed2 = " + sunboxed2);
            Console.WriteLine("value1 = " + svalue1);
            Console.WriteLine("value2 = " + svalue2);
    
            //Now try hand at custom types
            cvalue1 = new MyType() { Example = "I am cvalue1's original string." };
            cvalue2 = new MyType() { Example = "I am cvalue2's original string." };
    
            //now box them up.
            cbox1 = cvalue1;
            cbox2 = cvalue2;
    
            //now unbox and change the strings
            var cunboxed1 = cbox1 as MyType;
            var cunboxed2 = cbox2 as MyType;
    
            //change the original strings to see if they propogate to original objects
            cunboxed1.Example = "I am cunboxed1's altered string.";
            cunboxed2.Example = "I am cunboxed2's altered string.";
    
            //print unboxed and originals values to compare
            Console.WriteLine("cunboxed1.Example = " + cunboxed1.Example);
            Console.WriteLine("cunboxed2.Example = " + cunboxed2.Example);
            Console.WriteLine("cvalue1.Example = " + cvalue1.Example);
            Console.WriteLine("cvalue2.Example = " + cvalue2.Example);
    
            Console.ReadKey();
        }
    }
    
    class MyType
    {
        public string Example { get; set; }
    }
    

    测试者应用程序的结果:

    unboxed1 = -10  
    unboxed2 = -15  
    value1 = 10  
    value2 = 15  
    cunboxed1.Example = I am cunboxed1's altered string.  
    cunboxed2.Example = I am cunboxed2's altered string.  
    cvalue1.Example = I am cunboxed1's altered string.  
    cvalue2.Example = I am cunboxed2's altered string.  
    

2 个答案:

答案 0 :(得分:0)

您所看到的是由价值和参考类型的不同处理引起的。在第一个示例中,您正在装箱int。它包含在Int32中,是一种值类型,并已分配给您的object变量。在拆箱步骤中,会复制原始Int32对象,因为它是值类型,并且其值已分配给int变量sunboxed1sbox1sunboxed1拥有不同的值并存在于不同的内存位置,因此对其中一个进行的更改不会影响另一个。

在第二个示例中,您将一个类分配给object变量。这不是拳击它;您只是简单地向上转换对象的引用。当您随后使用MyType关键字将其向下转发回as时,您将获得对原始对象的引用。因此,cvalue1cunboxed1包含对同一对象的引用。

答案 1 :(得分:0)

正如dotnetom所说,这更多是关于价值与参考类型。

根据MSDN http://msdn.microsoft.com/en-us/library/t63sy5hs.aspx
数据类型是一种值类型,如果它将数据保存在自己的内存分配中。值类型包括以下内容: 所有数字数据类型....

然而,对于班级:
引用类型包含指向保存数据的另一个内存位置的指针。引用类型包括以下内容:类类型,例如Form .....

最后一行是最有趣的。
类是引用类型。因此,.NET Framework类支持引用类型(如Object和String)。请注意,每个数组都是引用类型,即使其成员是值类型

这就是为什么上面的自定义类型在解除拳击后更改了上面的原始值。字符串本身是引用类型,所以看起来改变的原因似乎是由于我使用字符串作为示例而不是数字类型;但是,将Example属性更改为int仍会更改原始源并产生相同的结果。