18

いくつかのクラス メソッド A で、パラメーターとして を受け取るライブラリ メソッド B を呼び出す必要がありIProgress<Object>ます。

通常、IProgress<Object>A が存在するクラスの一部として実装してから、「this」をメソッド B に渡します。または、IProgress<Object>それを正しく実装して処理することのみを目的とする新しいクラスを作成することもできます。 d そのクラスのインスタンスを作成し、それを B に渡します。

しかし、私が本当に望んでいるIProgress<Object>のは、呼び出し元のコードと実装の間の視覚的な切断が少なくなるように、B を呼び出しているメソッドのすぐ内側に の実装を表示することですIProgress<Object>。(私の IProgress の実装は、呼び出し元のメソッドのプライベートで共有されていない詳細のようなものであると考えているため、私の実装をIProgress<Object>おそらく他のクラス全体の完全に別のメソッドにしたくありません)。

私がやろうとしているのは、短い進行状況の処理を定義するラムダを使用し、このラムダを次のように B に渡すことです。

method in class A {
...
Action<Object> Report = (m) => { // do something useful with m };

B(Report)
}

method B(IProgress<Object> reporter) {
   reporter.Report(some object)
}

もちろん、これがそのままでは機能しない理由はわかっています。B は実装するオブジェクトを必要IProgress<Object>としており、代わりに Action オブジェクトを渡しています。

私が達成しようとしていることを達成する方法はありますか? IProgress<Object>(メソッド A 内に表示される場合、IE は私の実装を持っていますか?

4

5 に答える 5

16

デリゲートはインターフェイスを (直接) 実装できません。

2 つの適切なオプションが思い浮かびます。

  1. 呼び出しているメソッドの定義を、型ではなくデリゲート型を取るように変更しますIProgress。(可能であれば、これが望ましいオプションです)

  2. 必要なインターフェイスを実装し、その機能を実装するためのパラメーターとしてデリゲートを取る新しい型を作成します。

#2 の例は、インターフェイスに依存しますが、次のようになります。

interface IProgress<T>
{
    void doStuff(T param);
}

class LambdaProgress<T> : IProgress<T>
{
    Action<T> action;
    public LambdaProgress(Action<T> action)
    {
        this.action = action;
    }

    public void doStuff(T param)
    {
        action(param);
    }
}

次に、次のようなことができます。

B(new LambdaProgress<Object>(obj => ...));
于 2012-09-17T16:01:42.313 に答える
4

いいえ、インターフェイスが必要な場合、ラムダを指定することはできません。ただし、 impromptu-interface
を使用して匿名オブジェクトを提供できます。

この例は、そのプロジェクト ページからのものです。

//Anonymous Class
var anon = new
{
    Prop1 = "Test",
    Prop2 = 42L,
    Prop3 = Guid.NewGuid(),
    Meth1 = Return<bool>.Arguments<int>(it => it > 5)
}

var myInterface = anon.ActLike<IMyInterface>();

あなたの例では、これは次のようになります。

A
{
    // Create an anonymous object.
    var anonymous = new
    {
        // Define a method that needs an "object" parameter and returns nothing.
        Report = Return.Arguments<object>(m =>
        {
            // Do whatever you want to do when Report is called.
        })
    }

    // Get your anonymous object as an IProgress<Object>.
    var obj = anonymous.ActLike<IProgress<Object>>

    // Call B.
    B(obj);
}
于 2012-09-17T16:27:58.043 に答える
1

IProgress<object>インターフェイスに 1 つのメソッドだけがあり、API を制御すると仮定するとvoid Report(object)、現在タイプのパラメーターを必要とするメソッドを単純に再定義して、IProgress<object>代わりに新しいデリゲート タイプを必要とすることができます。

public delegate void ProgressReportDelegate(object someObject);

次に、例を次のように変更できます。

method in class A {
...
Action<Object> Report = (m) => { // do something useful with m };

B(Report)
}

method B(ProgressReportDelegate reporter) {
   reporter(someObject);
}

より複雑なインターフェイスの場合、または API を制御しない場合 (したがって、そのインターフェイスを実装するオブジェクトではなくデリゲートを取得するようにメソッドを変更できない場合)、これは実際にはオプションではありませんが、機能するように見えます。あなたの場合。

于 2012-09-17T16:00:21.373 に答える