2017-12-22 6 views
2

C言語からは、ポインタが別のポインタに割り当てられていることを覚えている限り、元の値にアクセスするために**接頭辞を使用します。c#コンパイラはコンパイル時に参照の参照を解決しますか?

オブジェクトインスタンスをref Myobject myObject引数としてメソッドに渡すと、これはどうなりますか? c#はオブジェクトのヒープアドレスを解決し、以下のようなコードでprintSomethingを呼び出しますか?

void testFunction(ref MyObject myObject){ 
    myObject.printSomething(); 
} 

したがって、これが再帰関数であれば、コンパイラはオブジェクトを見つけるまで参照アドレスに従いますか?

下記のテストシナリオを追加しています。

public class Test 
{ 


    public Test() 
    { 
     StringBuilder str = new StringBuilder(); 
     Function(ref str); 
     Console.WriteLine(str.ToString()); 
    } 

    int referenceCount = 0; 

    int Function(ref StringBuilder sBuilder) 
    { 
     referenceCount++; 

     if (referenceCount == 100) 
     { 
      sBuilder.Append("foo"); 
      return referenceCount; 
     } 

     Function(ref sBuilder); 
     return referenceCount; 
    } 

    public static void Main(string[] args) 
    { 
     new Test(); 
     Console.ReadLine(); 
    } 

} 

期待通りにブロックが各メソッドのように、フロー例外の上にスタックを与える場合、私は削除した場合は、新しい参照が相互にそれらの100をリンクstack.Afterに予約されて、私は最後の1のメソッドを呼び出しています呼び出します。 sBuilder.Append("foo");コードはオブジェクトに到達するまでリンク先の参照に従いますか?

+0

ポインタはオブジェクトの開始アドレスです。オブジェクトの構造は、C#とC言語で同じに定義する必要があります。 c#が管理されているため、オブジェクトはマーシャル技術を使用して管理されていないメモリに移動する必要があります。 2つのアスタリスクを使用することは、ポインタが配列へのアドレスのアドレスに対するアドレスであることを意味する可能性があります。コンパイルは何もしません。すべての正しい定義を行う必要があります。コンパイルはオブジェクトの開始アドレスをスタックに置くだけです。 – jdweng

+1

あなたの例で 'myObject'を再割り当てしていないので、' ref'キーワードはまったく役に立たないです。もちろん、 'printSomething'が与えられたインスタンスに対して呼び出されます。私は他のものを見ることができません。私はあなたが求めていることを理解していません。 – HimBromBeere

+0

私は事を少し明確にするテストシナリオを追加しました。私は自分自身をより鮮明にしたいと思う。 – trueLife

答えて

0

これを見てくださいarticle

c#のリファレンスはC++のポインタではありません。これは異なる概念です。

メソッドのパラメータリストで使用すると、refキーワードは、値ではなく参照で渡される を示します。参照渡しの の効果は、呼び出されたメソッドに呼び出された メソッドの引数の変更が反映されていることです。たとえば、呼び出し側 がローカル変数式または配列要素アクセス 式を渡し、参照先のメソッドが参照先 パラメータを参照するオブジェクトを置き換えた場合、呼び出し側のローカル変数または配列 要素は、新しいメソッドが戻るときのオブジェクト

関連する問題