0

我在 c# 中做了以下示例

    interface IChangeable
    {
        void Change(params Int32[] array);
    }

    struct SomeValueType : IChangeable
    {
        private Int32 m_X;

        public SomeValueType(int X)
        {
            m_X = X;
        }

        public void Change(params Int32[] array)
        {
            m_X = array[0];
        }

        public override string ToString()
        {
            return String.Format("Crt value of m_X: {0}", m_X);
        }
    }

在主要:

    static void Main(String[] args)
    {
        SomeValueType someValueType = new SomeValueType(5);
        Console.WriteLine(someValueType);                                   // No boxing occured. It showed: 5

        Object someRefType = someValueType;                                 // Boxed
        Console.WriteLine(someRefType);                                     // Also Shows 5 (from heap)

        someValueType.Change(2);                                            // Change Value of x not o's
        Console.WriteLine(someValueType + " " + someRefType);               // 2 5

        ((SomeValueType)someRefType).Change(3);                             // Copies to a temp stack so no change ocuured in o
        Console.WriteLine(someRefType);                                     // 5

        IChangeable itfStackChange = (IChangeable)someValueType;
        itfStackChange.Change(7);
        Console.WriteLine(someValueType);                                   // Shows 2 and not 7 ... why?

        IChangeable itfChange = (IChangeable)someRefType;
        itfChange.Change(1);                                                // Unboxes the value of o, making the value of x 1 boxes o again?
        Console.WriteLine(someRefType);                                     // Shows 1
    }

现在我想知道当我这样做时会发生什么:

        IChangeable itfStackChange = (IChangeable)someValueType;      //value was 2 and its still 2
        itfStackChange.Change(7);
        Console.WriteLine(someValueType);  

但是,如果我将结构的定义更改为类,例如:

class SomeValueType : IChangeable

它写的是 7 而不是 2。

4

2 回答 2

2

值类型语义使得值在赋值时被复制。这意味着当您在赋值后更改时,变量指向不同的对象。

对于引用类型,引用被复制,这意味着当您在赋值后更改时,两个变量都指向同一个对象。

请参阅MSDN 上的值类型和引用类型

于 2013-03-07T18:33:50.620 回答
0

A structure-type definition actually defines two kinds of things: a kind of storage location, and a kind of heap object which inherits from the abstract class System.ValueType. The heap object effectively has one field of the corresponding storage-location type, but exposes all the members of that storage-location type as though they were its own. To the outside world, the heap type will behave like a class object; internally, however, references to this are references to its field of the corresponding storage-location type.

Although C# defines the term "inheritance" in such a way as to pretend that the storage-location type and the heap-object type are one and the same, the two types will behave differently. Casting a value type to an interface that it represents will generate a new heap object which holds a copy of the public and private fields of the value type that was cast, and then return a reference to that new instance. The resulting reference will exhibit reference semantics, since it will be a reference.

If one regards heap objects and value-type storage locations as existing in separate universes, and recognizes the cases in which values must be copied from one universe to the other, one will find that such a model will accurately predict how things will behave.

于 2013-03-07T20:26:30.067 回答