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

2ではなく7を書き込みます。

4

2 に答える 2

2

値型のセマンティクスは、割り当て時に値がコピーされるようなものです。これは、割り当て後に変更すると、変数が異なるオブジェクトを指すことを意味します。

参照型の場合、参照はコピーされます。つまり、割り当て後に変更すると、両方の変数が同じオブジェクトを指します。

MSDNの値型と参照型を参照してください。

于 2013-03-07T18:33:50.620 に答える
0

構造型定義は、実際には2種類のものを定義します。1種類の格納場所と、抽象クラスから継承する一種のヒープオブジェクトSystem.ValueTypeです。ヒープオブジェクトには、対応するストレージロケーションタイプのフィールドが1つありますが、そのストレージロケーションタイプのすべてのメンバーは、それ自体であるかのように公開されます。外の世界では、ヒープ型はクラスオブジェクトのように動作します。ただし、内部的には、への参照thisは、対応する保管場所タイプのその項目への参照です。

C#では、「継承」という用語を、ストレージロケーションタイプとヒープオブジェクトタイプが同じであるかのように定義していますが、2つのタイプの動作は異なります。値型をそれが表すインターフェイスにキャストすると、キャストされた値型のパブリックフィールドとプライベートフィールドのコピーを保持する新しいヒープオブジェクトが生成され、その新しいインスタンスへの参照が返されます。結果の参照は、参照になるため、参照セマンティクスを示します。

ヒープオブジェクトと値型の格納場所が別々のユニバースに存在すると見なし、あるユニバースから別のユニバースに値をコピーする必要がある場合を認識すると、そのようなモデルは物事の動作を正確に予測できることがわかります。

于 2013-03-07T20:26:30.067 に答える