web-dev-qa-db-ja.com

「メソッドグループ」から「System.Action <オブジェクト>」エラーに変換できません

次の関数を作成しました:

public void DelegatedCall(Action<Object> delegatedMethod)

そして、次のメソッドを定義しました

public void foo1(String str) { }

ただし、foo1DelegateCallを呼び出そうとすると:

DelegatedCall(foo1);

...次のコンパイラエラーが表示されます。

Argument 1: cannot convert from 'method group' to 'System.Action<object>'

このエラーの理由は何ですか?また、どうすれば修正できますか?残念ながら、foo1Actionにキャストすることはオプションではありません。

41
Jonathan

DelegatedCallは、objectを引数として取るデリゲートを期待します。しかし、あなたの関数foo1に渡すDelegatedCallは、string引数にしか対処できません。したがって、変換はタイプセーフではないため、不可能です。

入力パラメーターはcontra-variantですが、コードにはcovariance。 ( 共分散と反分散の違い を参照してください。)

DelegatedCallをジェネリックにすることができます:

DelegatedCall<T>(Action<T> action)

...または任意のデリゲートを取る:

DelegatedCall(Delegate action)

しかし、それを実装するのは見苦しく、リフレクションが必要です。また、コンパイル時に関数にパラメーターが1つしかないことも確認しません。

28
CodesInChaos

分散はそのようには機能しません。あなたが必要だろう

_DelegatedCall(obj => foo1((string)obj));
_

4.0でさえ、すべてのオブジェクトが文字列であるとは考えていません。

すべての文字列isオブジェクトであるため、foo1(object)および_Action<string>_(つまり、逆の場合)である可能性があることに注意してください(4.0では)。

10
Marc Gravell