2012-01-24 10 views
0

(安全でないキーワードを使用せずに)ポインタを渡すシミュレートする方法があり、以下を達成することができる。、「安全でない」キーワードを使用しない

が関数にパラメータとして渡されたフィールドを持ちます。この関数は、そのフィールドの値を定期的に変更することができます。

ので、私が持っている場合:

int MyField; 

と:

MyFunction(ref MyField) 

機能がMyFieldへのポインタを格納することができ、必要に応じてその値を変更します。

C++では、値へのポインタを渡して必要に応じて変更するだけですが、これをC#で達成できるかどうかを調べようとしています。私はそれが反映されていると推測しています。

+3

これは、C++コードのヒープを破損させる一般的な方法です。ポインタを介して書き込みを続けるが、ポインタが指し示すオブジェクトを解放する。基本的に安全でない*。 C#コードでオブジェクトへの参照を渡すだけです。 –

+2

また、C#でC++プログラマになろうとしないと、涙が出る –

答えて

6

あなたは本質的に、リファレンスパラメータを使用することでこれをやっています。

+0

私は関連するビットが "MyFieldへのポインタを格納し、必要に応じて値を変更する"と思います。また、管理参照を後で使用するために保管することはできません。フィールドに入れることはできないからです。 – svick

2

refキーワードの使用は、コードがあなたが求めていると思わないようにするために明示的に設計されています(つまり、関数が関数 'exit'の後に 'ref'パラメータを介して渡される)。あなたがコードを無差別に持続させ、変更可能な参照を何かに渡したい場合は、それをラッパーオブジェクトのパブリックフィールドにするか、単一要素の配列をインスタンス化してそれを渡します。あなたはありません....あなたが参照を格納することはできませんのMyField

0

....

しかし、あなたはクラスや店舗でそれをラップすることができますそれを参照してください。

+0

ただし、このrefを保存してからメソッドの範囲外で引き続き使用することはできません。 – perfectionist

+0

@perfectionist本当ですが、私はそれがOPが求めていたものだとは思いません。 –

0

への参照を渡しているRef parameterを使用することにより

10

は私がその質問を言い換えるてみましょう:

私は私のコードは、後に変数を更新できるように参照を格納メソッドにパラメータとして変数への参照を渡すことはできますか? CLR型システムの参考文献に

変数へが仮パラメータとして渡すことができます。それらはまた、短寿命であることが知られているローカル変数として知られているとのメソッド呼び出しから返されたである場合があります。 (C#は後者の2つの機能をサポートしていません(詳細については、件名に関する記事を参照してください:http://blogs.msdn.com/b/ericlippert/archive/2011/06/23/ref-returns-and-ref-locals.aspx

ただし、フィールドまたは配列に格納することはできません。簡単に言えば、変数への参照は、短命であることが知られている場所にのみ格納することができます。

あなたが同時にでこれらの望ましい資質のすべての4つを持つことができないので、この制限の理由は次のとおりです。

  • どれ変数が参照渡しすることができ
  • アクセスすることは常に安全です変数への参照(安全なコードで、変数が安全でないコードからの逆参照である場合、は実行時ではなく安全性を保証する責任があります)
  • 短命変数はgarbaなしでクリーンアップできます(つまり、「スタックをポップする」またはレジスタを再利用することによって、または短期間のストレージプールに使用される他の非Gcベースのストレージ再生システムによって)。
  • 可変参照は、

これらのうちの1つが与えられていますが、CLR設計者は最後の1つを敗者として選択しました。 CとC++の設計者は、失うものとして2番目を選択しました。

私はそれが反射によって行われると推測しています。

できません。しかし、それは代理人で行うことができます。

class C 
{ 
    private Action<int> setter; 
    public void RecordSetter(Action<int> setter) 
    { 
     this.setter = setter; 
    } 
    public void SetIt(int x) 
    { 
     this.setter(x); 
    } 
} 

、今あなたが言うことができます。

class D 
{ 
    int myField; 
    void M() 
    { 
     C c = new C(); 
     c.RecordSetter(x=>{myField = x; }); 
     c.SetIt(123); 
     Console.WriteLine(myField); 
    } 
} 

ガベージコレクタがDのインスタンスは、Cのインスタンスが生きたままのように長く生きたままことを保証します。

関連する問題