0

匿名関数パラメーターを受け取るメソッドがあります。この関数のパラメーターは、ローカル変数によって提供されます。

public void DoSomething<T>(Action<T> method) where T : new()
{
    T instance = new T();
    method.Invoke(instance);
}

クロージャーを作成しないようにしたい。終了すると、ローカル変数はスコープ外にDoSomething<T>なります。コンパイル時に制約する方法はありますか?

これが私が避けたい状況です:

Foo capturedInstance = null;
DoSomething<Foo>(item => capturedInstance = item);
capturedInstance.Call();
4

3 に答える 3

1

構造体の場合、型のフィールドまたは型の配列Tを保持するコードが、フィールドまたは配列要素をパラメーターとして外部メソッドに渡すことができます。そのメソッドは、構造体の一時的なコピーを作成することなく、そのフィールドまたは配列スロットで直接かつ効率的に動作できますが、メソッドがフィールドまたは配列を保持する型を返すと、外部コードがそのスロットにアクセスできなくなると確信できます。 。もちろん、Outsideはフィールドまたは要素の内容のコピーを作成することもできますが、構造体を保持する型が再び外部コードに公開しない限り、元のコンテンツを変更することはできません。TT[]ref

残念ながら、Tが可変クラスである場合、参照を公開すると、外部コードがその参照を無差別にコピーして、永久に渡すことができます。そのため、可変クラスは可変構造体よりもはるかに悪いデータホルダーです。直接参照を公開せずに外部コードでクラスを使用できるようにする場合は、ラッパークラスとインターフェイスを作成する必要があります。残念ながら、これを行うには、本当に恐ろしい量の重複コードを使用するか、Reflectionを使用して実行時にラッパーを生成する必要があります。

于 2012-05-30T21:09:32.743 に答える
1

残念ながら*、それは不可能です。メソッドがその引数をどのように処理するかを制御することはほとんどできません。ジェネリック型を使用していなければ回避することは可能ですが、使用しているので、そのような状況について心配する必要はありません。(私はあなたがそうする必要がないことを望みます。)


※実は「幸い」と思います。これは、ここで話しているC++ではありません。

于 2012-05-17T22:56:55.427 に答える
-1

私はあなたのコードがすでにあなたが望むことをしていると思います。ラムダを表すデリゲートitem => capturedInstance = itemはにのみ渡されDoSomething<Foo>、その参照は他の人に渡されません。したがって、包含メソッドが終了すると、デリゲートはスコープ外になります。また、ラムダ式によってキャプチャされるローカル変数も同様です。デリゲートへの参照を渡す場合にのみ、希望する動作を得ることができません。

于 2012-05-17T23:14:58.227 に答える