C#およびメソッドパラメーターへの参照の格納
-
06-07-2019 - |
質問
ちょっとした背景情報として、ループで実行されているアプリケーションがあり、それをチェックするとTickメソッドが呼び出されます。基本クラスを拡張し、すべてが独自のティックメソッドを持ち、クラスAが呼び出され、そのチェーンにBとCのインスタンスがある場合、B.Tickが呼び出されるように、依存クラスに追加されるクラスの束があります、C.Tick、A.Tickの順に続きます。
したがって、擬似コードでは、私のクラスは次のようになります。
public class A : Super
Super b;
Super c;
ArrayList one;
ArrayList two;
tick(){
one.Add(b.LastValue);
two.Add(c.LastValue);
... do something with one and two ...
}
A(){
b = new B(some other array list);
c = new C(ref one);
}
Bは正常に機能しており、常に正しい値を取得します。問題は、クラス内の別の変数への参照を保存できないと思うので、新しいC(ref one)を実行するときです。そして、Cのコンストラクターはクラス変数を1に設定します。後でAで1が更新された後、Cはもう1つ(現在は更新されている)を指しているはずで、空になっている(元のように)コンストラクター内にありました)。 C#ポインターと安全でないコードを使用せずに、私が探していることを達成する方法についてのアイデアはありますか?ありがとう、うまくいけば:)
編集: どうやら実際の質問とはまったく関係のない紛らわしい擬似コードで質問に答えることができないようです。そのため、変更は次のようになります。
編集2:Cクラス
...
ArrayList local;
...
C(ref ArrayList one){
local = one;
}
Tick(){
LastValue = local[0] + 5; //not actual formula, just shows trying to use a referenced variable
}
解決
one
はArrayListであるため、参照としてのみを渡すことができます。これで、コンストラクタへの参照への参照として渡すようになりました。その ref
は必要ないかもしれません。
しかし、あなたが達成しようとしていることのより完全な考えを示してください。
編集:
Cクラスを見た後、 ref
は必要ありません。 c
は、Aが one
を呼び出すArrayListのインスタンスを共有します。
これは、.NETの一般的なreferencetype / valuetypeの問題に要約されるようです。要約すると:
- オブジェクトのインスタンスには名前がなく、(物理的に)パラメーターとして渡すことはできません。
- 常に参照を通じてインスタンスにアクセスします。コードでは、
one
(2x)、two
、local
はすべてArraylistインスタンスへの参照です。 - 参照自体は値型のように動作します。つまり、代入はコピーを意味します。
referencetypes / valuetypesの詳細については、「コピーセマンティクス」を検索し、「valuetypes exists on the stack」で始まる投稿を避けてください。
他のヒント
これを行うことを妨げるものは何もありません。しかし、それが良いアイデアかどうかは別の質問です。一般的に、メソッド呼び出し間で状態を変更できないようにすることを避けることをお勧めします。もちろん、そこにあるキー式には「回避できる場合」があります。 :-)
クラス内の別の変数への参照を保存することはできません
できます、人々はいつもそれをします。 (プライベート)フィールドに割り当てるだけです。
そのため、新しいCを実行するとき(ref one)。 [snip /]後でAで1つが更新された後、Cがまだ1つを指していることになっていることを認識していないようです
実際には、それは知っていますが、メンバーフィールドに one
を割り当てる必要があります。オブジェクトへの割り当ては、オブジェクトへの参照を設定する以上のものではありません。オブジェクトを変更し、割り当てたすべての場所でそれらを変更します。
class A
{
public string Hello { get; set; }
}
class C
{
private A myA;
public C(A a) { myA = a; }
public A GetMyA() { return myA; }
}
// somewhere else:
A someA = new A();
someA.Hello = "Hello World";
C someC = new C(someA);
someA.Hello = "Other World";
Console.WriteLine(someC.GetMyA().Hello);
// this will print "Other World" and not "Hello World" as you suggest
PS:あなたは擬似コードを投稿していたので、少し単純化してもかまわないことを願っています。あなたの質問を誤解した場合は、無視してください(可能であれば、おそらく明確にしてください)。
PPS:(編集された)コードを読み直し、それでも問題が何であるかを理解しようとしていますが、コード内の C
が参照を保持することを妨げるものはないようです A
への呼び出しと a.Add
の呼び出しは、明らかに c
のメンバー変数も反映します。実際、ここに ref
は必要ありません。