3

次のように、ラムダ式でメソッドグループを使用しようとしています。

public class Foo { public void Hello(string s) { } }

void Test()
{
    // this works as long as Hello has a void return type
    Func<Foo, Action<string>> a = foo => foo.Hello;
}

ただし、のリターンタイプをに変更するHelloと、int

'Bar.Hello(string)'の戻りタイプが間違っています。

Funcの代わりに試してみましActionたが、メソッドグループ構文を使用できなくなっているようです。

何か案は?

(私の目標であるfwiwは、さまざまな戻り値と多くの文字列引数を持つ多数のメソッドを参照できるようにすることです。それらを呼び出すつもりはありません。属性を反映したいだけです。安全性が気に入っています。ただし、ラムダの数は、メソッド名の文字列を入力するだけではありません。)


編集:使用したい理由を明確にするためにAction<string>int私の例では、いくつかのタイプのいずれかである可能性があります。そのタイプをテンプレート化してみました-

void Set<T>(Func<Foo, Func<string, T>> a) { }
void Test() { Set(foo => foo.Hello); }  // fails

-しかし、コンパイラは派生できませんT(おそらく、リターンタイプでオーバーロードできないのと同じ理由で?)。

他のアイデアはありますか?この場合、コンパイラにそのメソッドグループの名前をチェックさせることができる限り、私はいくつかのクレイジーな反省に反対していません。

4

2 に答える 2

7

void以外のreturnタイプの場合、。との互換性はなくなりAction<string>ます。言い換えれば、これも失敗します:

int Foo(string s) { return 10; }

// Error: wrong return type
Action<string> action = new Action<string>(Foo);

これが許可されない理由については、EricLippertの「voidisinvariant」に関するブログ投稿を参照してください。

次のようなメソッドグループ構文を使用できるはずです。

public class Foo { public int Hello(string s) { return 10; } }

void Test()
{
    Func<Foo, Func<string, int>> a = foo => foo.Hello;
}

これは、VS2008とVS2010の両方で機能します。C#4のメソッドグループ変換と型推論にいくつかの変更がありました-残念ながら詳細はわかりません-しかし、このケースはこれらの変更の影響を受けないと思います。

于 2010-10-22T10:14:29.803 に答える
6

void returnタイプの場合、foo.HelloはAction<string>です。int return型を使用すると、これは。になりFunc<string, int>ます。

複数の戻り型を処理するために(そして戻り値で何もする必要がないと仮定して)、次のように非void関数を簡単にラップできます。

Func<Foo, Action<string>> a = foo => s => foo.Hello(s);
于 2010-10-22T10:15:25.403 に答える