ページ 1 / 1
[C#]先に値型の変数を返して、後から参照でその値を変更したい
Posted: 2016年10月05日(水) 19:50
by moba
こんばんは。お世話になります。
C#で次のようなことをしたいです。
コード:
public void Test()
{
var obj = new TestObject();
var result = TestObject.MethodA(); // 値型の変数を受けとる
TestObject.MethodB(); // 【!】resultの値が変更される
// この行に来たとき、resultにMethodBの"結果"が入っている
}
どうしても上のように書きたいのですが、何か方法をご存知でしたら教えていただけませんか。
よろしくお願いします。
Re: [C#]先に値型の変数を返して、後から参照でその値を変更したい
Posted: 2016年10月05日(水) 20:27
by hide
オフトピック
そんなことが簡単にできたら私はC#を捨てます。クソです。
Re: [C#]先に値型の変数を返して、後から参照でその値を変更したい
Posted: 2016年10月05日(水) 21:22
by inemaru
C#詳しくないですが、
少なくとも、どこかに result の参照を退避させないと
result にアクセスする事すらできないので変更とか無理なんじゃ・・・
Re: [C#]先に値型の変数を返して、後から参照でその値を変更したい
Posted: 2016年10月05日(水) 22:52
by Idra
そのままでは無理なので妥協が必要ですね。
一つ目の方法は、値型ではなくて参照型を使う。
二つ目は、MethodBにresultを参照渡しする。
最後に、resultをフィールドにしてインスタンスを通して値を変更する。
Re: [C#]先に値型の変数を返して、後から参照でその値を変更したい
Posted: 2016年10月06日(木) 01:19
by YuO
参照戻り値と参照ローカル変数を使いたい、ということでしょうか。
そうであるならば、C#7で利用可能です。
Roslynの最新版をコンパイラとして使っているような環境で無ければ、次のVisual Studioあたりに付属するバージョンのコンパイラから利用可能になるでしょう。
今すぐ必要ならば、
Roslynのmasterブランチあたりをビルドして、コンパイラをすげ替えてやれば使えるかと。
# というか、
Visual Studio “15” Preview 4とかを使えばref returns and localsは使えるはず。
refs)
構文や制限は上記の記事を見てもらうとして、実際に使う場合はパフォーマンス上の問題が発生するような場合に限る方がよいとは思います。
本当にやりたいことは、objに紐付いた値型のオブジェクトであって、result自体が変更される必要は無いのではないでしょうか。
# resultはobjへの参照を内部に持っていて、objの内部プロパティなどを経由して値をとってくる、というようなもの。
それであれば、ref returns and localsを使う必要はないでしょう。
Re: [C#]先に値型の変数を返して、後から参照でその値を変更したい
Posted: 2016年10月06日(木) 19:05
by moba
すみません、背景を端折って質問していました。次から背景まで書きます<(_ _)>
IEnumerable<T>を返値とする関数を呼ぶと作られるオブジェクト(のEnumerator)を、コルーチンと呼ぶことにします。
コルーチンAからBを呼ぶときに、次のようにしたいです。
・コルーチンBが終了するまでコルーチンAに制御を戻さない
・コルーチンBの「最終結果」をコルーチンAに返す
そのために、コルーチンを実行するオブジェクト(プロセッサと僕は呼んでいます)を用意しています。
プロセッサが上の2つを実現してくれます。
プロセッサがいる前提で、コルーチンAからBを呼ぶコードを2つ考えました。
コード:
(1)
var result = YiledTo(CoroutineB()); // プロセッサに暗黙的にコルーチンを返す
yield return;
// この行に来たときコルーチンBは終了しており、resultにBの結果が入っている
// 追記:質問内容は、このときresultが値型だと、プロセッサはコルーチンAのローカル変数resultに値を返せないか、ということでした。
(2)
var resultBox = YieldTo(CoroutineB()); // resultBoxはclass(参照型)
yield return resultBox; // コルーチンをラップしたものを明示的にプロセッサに返す
var result = resultBox.Result; // コルーチンBの結果を取り出す
> hideさん、inumaruさん
ありがとうございます。やっぱりほとんど不可能みたいですね。
当たり前のことのように見えても、自分では判断がつかないので、回答していただけて助かります。
> idraさん
ありがとうございます。
(1)の書き方で、例えばint型のように振る舞う何かを返すことはできないでしょうか。
> YuOさん
ご丁寧にありがとうございます。
(1)の書き方が大事だったのですが、背景の説明をしていなかったのが悪かったですね。
すみません。
Re: [C#]先に値型の変数を返して、後から参照でその値を変更したい
Posted: 2016年10月06日(木) 20:32
by moba
(1)の補足です。(2)のコードは省略します。
コード:
IEnmerable<SomeClassB> CoroutineB()
{
...
yield return; // nフレームのウェイトなどの処理を挟める
...
yield return someClassInstance; // プロセッサに最終結果を返す(プロセッサが呼び出し元に渡す)
yield break;
}
IEnunerable<SomeClassA> CoroutineA
{
...
yield return; // nフレームのウェイトなどの処理を挟める
...
var result = YieldTo(CoroutineB()); // YieldToは暗黙的にプロセッサにコルーチンを渡します
yield return; // プロセッサに制御を返す(→コルーチンBが実行され結果が返される)
...
}
(1)の書き方はやはりできないらしい、ということで解決にしました。
今回もありがとうございました(^o^)o