クラスがPerson
あり、次のようなものがあるとします。
Person A = new Person("Tom");
Person B = A;
、に新しいPerson
を割り当てた場合に同じインスタンスも参照するように変更する方法はありますか?関数のパラメーター割り当てでそれを行うことができることを私は知っています。B
B = new Person("Harry")
A
ref
更新:ここで説明する機能がC#7に追加されました。
必要な機能は「reflocals」と呼ばれ、C#ではサポートされていません。
CLRは、refローカルを含むコードの生成をサポートしています。数年前、私は、機能するかどうかを確認するために、必要な機能を備えたC#の実験バージョンを作成しました。あなたは次のようなことをすることができます:
Person a = whatever;
ref Person b = ref a;
そして、あなたが言うように、「b」に変更すると「a」の内容が変更されます。2つの変数は、同じ保存場所のエイリアスになります。
これはちょっとした機能でうまく機能しましたが、C#では使用しないことにしました。それが言語の仮想的な将来のバージョンでまだ発生する可能性はありますが、私はそれについて期待してすべてを興奮させることはありません。それはおそらく起こらないでしょう。
(Microsoft製品の仮想的な将来のバージョンに関するEricの考えはすべて、娯楽目的のみであることに注意してください。)
いいえ、安全なコードでは不可能です(ref
関数パラメーターを超えて)。安全でないコードでは、ポインターを使用してそれを実現できる可能性がありますが、それは良い考えではないと思います。
A
値として「Tom」への参照が含まれています。A
それが指す場所を変更するには、への参照が必要です。
クラスのインスタンスを暗黙的に参照として扱うのではなく、明示的にポインターを使用する言語で同様のコードを検討する場合:
Person* A=new Person("Tom");
Person* B=A;
B=new Person("Harry");//Changes only B
Person** C=&A;
(*C)=new Person("John");//Now A changes
したがって、を変更するには、ポインタへのポインタが必要ですA
。これをC#に転送する場合は、ローカル変数への参照が必要になります。そして、それらはref
関数パラメータの形でのみ利用可能です。これにより、ローカル変数への参照がそのローカル変数よりも安全に存続できないため、ライフタイムの問題を回避できます。
これらがプライベート変数でない場合は、BをセッターのAを変更するプロパティにすることができます。
Person B{get{return A;} set{A=value;}}
それを行う直接的な方法はありません。
次のようなソースコードアプローチをとることができます。
A = B = new Person("Harry")
または、ジェネリック型を使用します。何かのようなもの:
var A = new ReferenceHolder<Person> (new Person("Tom"));
var B = A;
C#では、ポインター(基本的にはrefタイプ)を使用することもできますが、そのアプローチは静的に検証できず、推奨されません。