2011-02-05 20 views
5

説明してください。参照型が値型の内部に定義されているとどうなりますか。 、内に常駐ReferenceTypeの値が50に変更されたかの方法Test(ObjVal, ObjValRef)を呼び出した後、私が知って興味クラス内部構造

 
ValueType: 10 
ReferenceType Inside ValueType Instance: Reference Type: 10 
Reference Type: 10 
ValueType: 10 
ReferenceType Inside ValueType Instance: Reference Type: 50 
Reference Type: 50 

を:

namespace ClassInsideStruct 
{ 
    class ClassInsideStruct 
    { 
     static void Main(string[] args) 
     { 

      ValueType ObjVal = new ValueType(10); 
      ObjVal.Display(); 

      ValueType.ReferenceType ObjValRef = new ValueType.ReferenceType(10); 
      ObjValRef.Display(); 

      Test(ObjVal, ObjValRef); 

      ObjVal.Display(); 
      ObjValRef.Display(); 

      Console.ReadKey(); 

     } 

     private static void Test(ValueType v, ValueType.ReferenceType r) 
     { 
      v.SValue = 50; 
      r.RValue = 50; 
     } 

    } 

    struct ValueType 
    { 

     int StructNum; 
     ReferenceType ObjRef; 

     public ValueType(int i) 
     { 
      StructNum = i; 
      ObjRef = new ReferenceType(i); 
     } 

     public int SValue 
     { 
      get { return StructNum; } 
      set 
      { 
       StructNum = value; 
       ObjRef.RValue = value; 
      } 
     } 

     public void Display() 
     { 
      Console.WriteLine("ValueType: " + StructNum); 
      Console.Write("ReferenceType Inside ValueType Instance: "); 
      ObjRef.Display(); 
     } 

     public class ReferenceType 
     { 

      int ClassNum; 

      public ReferenceType(int i) 
      { 
       ClassNum = i; 
      } 

      public void Display() 
      { 
       Console.WriteLine("Reference Type: " + ClassNum); 
      } 

      public int RValue 
      { 
       get { return ClassNum; } 
       set { ClassNum = value; } 
      } 

     } 

    } 

} 

出力: 私は、次のコードを記述しますValueType値は変更されていませんか?

+1

構造体へのクラスの位置は無関係です。これはちょうどネストされた型です(C#ではJavaやScalaと異なり、囲み型に依存しません)。 'ReferenceType'がネストされていないのと同じセマンティクスです。型と変数を、指定された型とインスタンス化された型のオブジェクトと混同しないでください。 –

答えて

2

私は確かに分かりませんが、コンパイラはおそらくコードを別のクラスに分けて、必要なルールを強制します。値型を使用すると、値はメソッドに渡されるたびにコピーされます。参照型への参照はコピーされますが、同じオブジェクトを参照します。 コピーされた値のタイプが変更される間、この同じ参照オブジェクトが変更されます。あなたが渡したオリジナルはコピーの変更を反映しません。

+0

+1「コピー」が明示的に言及される方法が好きです。この要件は、実際の実装とは独立した構造型呼び出しのセマンティクスを保持します。 –

1

値の内部値型は参照であり、変更されていません。しかし、参照によって指摘される価値は容易に変更することができます。

2

参照型は参照型であり、値型は値型であるためです。どこに住んでいても。

また、値のタイプは参照の保持を変更していません。 変更されるリファレンスタイプ(私の言葉を慎重に読んでください)

つまり、そのアドレスの基になるデータが変更されます。値の型で保持されている参照はまだ同じです。

+0

私はこれの始まりが好きです。多分、オブジェクトt = Guid.New; f(t) ' –

+0

@pstそれは新しいですGuid.NewGuidです。値の型Guidの構造体を返し、オブジェクトにボックス化され、参照はtに与えられます... BTWは何をしていますか... –

1

参照型はメソッドとしてポインタとして渡されるため、内容を変更するとメモリ内の同じ場所が変更されます。値の型は、コールスタックに値を送信することによってメソッドに渡されます。プログラミング時

+1

そしてポインタが送られます... dum dum dum ... asスタック上の値!この答えは間違っているわけではありませんが、重要な違いは、セマンティクスが、参照型オブジェクトの*コピー/複製*がパスされたときに行われないということです(これは* lifted * value-types )。セマンティクスを保持するためにコピー/クローンが作成された場合、値型オブジェクト*も "参照"によって渡すことができます。実装は単なる実装にすぎません。 –

-1

、それはが引数を取るメソッドを呼び出すことを理解することが重要です意味/含ん/これらの引数から割り当てる値と同じです。プラス:

static void Main(string[] args) 
{ 

    ValueType ObjVal = new ValueType(10); 
    ObjVal.Display(); 

    ValueType.ReferenceType ObjValRef = new ValueType.ReferenceType(10); 
    ObjValRef.Display(); 

    //call to Test(ObjVal, ObjValRef); replaced by the following 4 lines 
    ValueType v = ObjVal; 
    ReferenceType r = ObjValRef; 
    v.SValue = 50; 
    r.RValue = 50; 

    ObjVal.Display(); 
    ObjValRef.Display(); 

    Console.ReadKey(); 

} 

は、上記の例と同じ結果が得られます。宣言するときValueType v = ObjVal;実際の構造体オブジェクトのコピーを作成しています。つまり、vは別々のオブジェクトです。メンバーの値を変更してもObjValには影響しません。

ただし、ReferenceType r = ObjValRef;は、のコピーを参照番号にします。したがって、2つの参照、ObjValRefrが同じオブジェクトを指しています。すなわち、を呼び出すときに作成されたオブジェクト新しいValueType.ReferenceType(10);オブジェクトの変更メンバーは、これらの2つの参照のいずれかによって指さ場合

ようにかかわらず、このオブジェクトの変更は、そのポインタが変更を実行するために使用されます。

oh、by by ..参照は単なるオブジェクトのアドレスです。多くの場合、これは32ビットの数値ですが、言語ごとに変わり、プロセッサーごとに変わります。

であり、参照コピー自体を変更する。 r = null;は、元の参照ObjValRefには影響しません.rはObjValRefのコピーであり、ObjValRef自体ではないからです。同じオブジェクトを指しているので、同じであるかのように見えます。

実際のオブジェクトは、場所(公園や有名な建物、おそらく「ホワイトマウンテンパーク」)とこの場所を指す通りの標識としての参照として考えることができます。同じ場所を指す多くの通りの標識があるかもしれませんが、これは多くの「白山公園」があることを意味するものではありません。これは値型と参照型の違いです。

+0

私は、なぜ「r」の価値が変わったのか理解しました。私はなぜ「v」の「RValue」が変更されたのかを知りたかったのです。しかし、値の種類と参照の種類を明確にしてくれてありがとう。 – NaveenBhat

+0

まあ、実際にはそうではありません。 RValueは同じ値を持ちます。これはオブジェクトのアドレスです。このオブジェクトは、内部的に変更されました(メンバーClassNumは50に設定されています)。本当に正確であるためには、2つのR値が必要です。 1つはObjValと呼ばれる構造体オブジェクトの内側にあり、もう1つはv。と呼ばれるstructオブジェクトの内側にあるメソッドTestの内部にのみ存在します。 vが作成されると、ObjValからのすべてのデータがvにコピーされます。これには、実際には32ビット整数であるRValueが含まれ、ValueType.ReferenceType型のオブジェクトのアドレスを指します。 – davogotland