イテレータ構文を使用してC#でイテレータ関数を記述すると、コンパイラは内部的に関数をクラスに変換します。私はこのような何か書くのであれば、:C#の参照パラメータに対応するオブジェクトフィールドの検索
IEnumerator<int> MyIterator() {
for (int i = 0; i < 10; i++)
yield return i;
}
呼び出すMyIteratorを()の代わりにスタック変数を使用して、私のためのプライベートフィールドを持つクラスを作成します。質問の今
:私は私の値を格納するために使用するフィールドを検索する方法を見つけたいです。その理由は、少し複雑です:
私は協力スレッドのためのイテレータ関数を使用しています。非同期操作が完了するまで関数の実行を中断するために、このような単純なコードをイテレータに書きます。
Future<string> f;
yield return file.readLine(out f);
string line = f.Result;
これら3つのステートメントが実行されると、readLine関数が呼び出され、未来が 'f'フィールドに格納されます。イテレーター関数は中断され、 'f' Futureに結果が格納されるとウェイクアップして、その時点で結果を取得できます。私が行うことができるようにしたいどのような
が、これは次のとおりです。スタック変数が生きたままことを保証する方法がないので、通常の状況下では
string line;
yield return file.readLine(out line);
、これは、.NETで可能ではないでしょう私がそれに書き込むことができるように十分長い。
しかし、反復子関数がすべてのローカルをフィールドの中に格納することを知っているので、私は理論的にはiteratorへの参照を保持することで(それを生かしておくことで)、フィールド自体にも渡すことができるので、readLine操作が完了すると、結果をフィールドに直接格納することができます。
問題は、CLRは私にこれを行う方法を提供していないようだということです。私が「アウト」または「REF」パラメータを使用している場合
は、私は生のポインタ、参照、またはTypedReferenceにそのパラメータを変換するために安全でないC#または生MSILを使用することができます。残念ながら、フィールドにこれらの3つのタイプのいずれかを格納することは合法ではありません。コンパイラを騙しても、バイトコード検証プログラムはコードを実行させません。これは、スタック変数への参照の格納が本質的に安全ではないためです。
だから、私は何を探していることはアウト/ refのパラメータを取り、対応するフィールドを見つけるために呼び出すイテレータのフィールドを検索する関数を記述です。フィールドがあれば、イテレーターとフィールドへの参照をラッパー・タイプに保管し、ラッパーを非同期操作に関連付けます。 .NETのランタイム反射に伴うオーバーヘッドを考えると
は、私はこれが私のソースコードを前処理またはコンパイルした後、私のアセンブリを後処理のいずれかなしには不可能であると思われます。
しかし、代替ソリューションの提案をお待ちしています。 :) 何か案は?
今後例では、多かれ少なかれ、あなたが記述の目的を果たします。毎回コンテナから値を取り除く必要があるので、私はそのステップをスキップして、できれば直接フィールドに書きたいと思います。 イテレータのフィールドを変更するセマンティクスは私には明らかです。イテレータのために生成されたILを見ると、あなたが正常に行う限り、ローカルを変更することは完全に安全です。 –