c#当需要接口时是否可以提供lambda?

时间:2012-09-17 15:53:22

标签: c# interface lambda

在某些类方法中,A,我需要调用一个库方法B,它以IProgress<Object>作为参数。

通常,我可能会将IProgress<Object>实现为A所在的类的一部分,然后将“this”传递给方法B.或者我可能创建一个新类,其唯一目的是实现{{1}并正确处理它 - 然后在这种情况下,我将创建该类的一个实例并将其传递给B.

但我真正想要的是让IProgress<Object>的实现出现在我调用B的方法中,这样调用代码和{{之间的视觉断开连接就更少了。 1}}实施。 (我认为我对IProgress的实现是一种私有的,非共享的调用方法细节,因此我不希望我的IProgress<Object>实现在一个完全独立的方法中,也许是整个其他类)。

我一直在尝试做的是使用lambda,我将在其中定义我的简短进度处理,然后以某种方式将此lambda传递给B,如下所示:

IProgress<Object>

当然,我知道为什么这不会按原样运行--B想要一个实现IProgress<Object>的对象,而是将它交给一个Action对象。

有没有办法实现我想要实现的目标? (如果method in class A { ... Action<Object> Report = (m) => { // do something useful with m }; B(Report) } method B(IProgress<Object> reporter) { reporter.Report(some object) } 出现在方法A中,IE有我的实现吗?

4 个答案:

答案 0 :(得分:13)

代表无法直接实现接口。

我想到了两个不错的选择:

  1. 更改您要调用的方法的定义,使其采用委托类型而不是IProgress类型。 (如果可能的话;这将是更好的选择)

  2. 创建一个实现所需接口的新类型,并将委托作为参数来实现该功能。

  3. #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 => ...));
    

答案 1 :(得分:4)

不,当需要接口时,您无法提供lambda 但您可以使用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);
}

答案 2 :(得分:1)

假设您的IProgress<object>界面只有一个void Report(object)方法,并且您控制了API,您只需重新定义当前需要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的地方(因此无法更改接受委托的方法而不是实现该接口的对象),这不是一个真正的选择,但它会似乎适合你的情况。

答案 3 :(得分:-1)

使用.NET 4.5,您可以使用Progress class