web-dev-qa-db-ja.com

ラムダ式はデリゲート型ではないため、「オブジェクト」型に変換できません

次のようなboolプロパティを持つ基本クラスがあります。

public abstract class MyBaseClass
{
     public bool InProgress { get; protected set; }
}

私はそれから別のクラスを継承し、InProgressを辞書のデリゲートとして追加しようとしています。しかし、それは私にエラーをスローします。これは私の派生クラスがどのように見えるかです:

public abstract class MyClass
{
     Dictionary<string, object> dict = new Dictionary<string, object>();
     dict.Add("InProgress", InProgress => base.InProgress = InProgress);

}

これは私が得ているエラーです:

ラムダ式はデリゲート型ではないため、「オブジェクト」型に変換できません

ここで何が間違っていますか?

29
Asdfg

辞書を強く型付けするのが最善ですが、最初にラムダを特定のラムダ(デリゲート)に割り当てると、動作します(コンパイラはデリゲート形式を知っているため)。

        Action<bool> inp = InProgress => base.InProgress = InProgress;
        dict.Add("InProgress", inp);

または直接キャストすることにより、同じ効果

       dict.Add("InProgress", (Action<bool>)(InProgress => base.InProgress = InProgress));

もちろん、そのような辞書形式をオブジェクトとして持つことは議論の余地があります。それを使用するにはデリゲート形式を知る必要があるからです。

25
Me.Name

行方不明になったときにこのエラーが出ました

using System.Data.Entity;
11
Craig Howard

@ Me.Nameによる解決策はそれ自体で完全に有効ですが、状況によっては役に立つかもしれない追加のトリックがあります(確かに私にとってはそうでした):これを使用して複数のラムダを変換する場合テクニックでは、次の行に沿って、ヘルパーメソッドとしてキャストを因数分解できます。

object myDelegateToObject ( Action<bool> action ) {
    return action; // autocast to `object` superclass, no explicit cast needed
}

それから単に呼び出す

dict.Add("InProgress", myDelegateToObject(InProgress => base.InProgress = InProgress));

後で時間を節約できる場合があります。署名を変更するために変更する場合は、1か所で変更する必要があります。

2
vaxquis

ユニットテストの作成中にこの問題に遭遇しました。データベースに実際に接続するのではなく、リポジトリから新しいオブジェクトを返すようにデータベースの動作を模擬しようとしました。

オブジェクトに使用可能なコンストラクターがあることを確認してください。目的の方法でそのオブジェクトを正常にインスタンス化できない場合があります。ラムダを使用してコンストラクターを指す場合は、通常のインスタンス化ステートメントでコンストラクターを同じ方法で呼び出すことができることを確認してください。

つまり.

return x => new FakeObject();

の場合に言う

var fake = new FakeObject();

動作しない場合、ラムダも失敗するので注意してください。

0
David Hunsicker