匿名接口实现

本文关键字:实现 接口 | 更新日期: 2023-09-27 18:14:48

我读过' c#匿名实现接口(或抽象类)'线程匿名实现接口。但我想知道,如果使用。net 2.0 (NO LINQ),使用委托或任何类似的方法,这是否也可能。我从JAVA中知道以下可能:

MyClass m = MyMethod(new MyInterface() {
    @override
    public void doSomething() {...}
}

(我希望我记得很清楚,是一段时间以前,我使用JAVA,但我想它是类似的)。当一个方法需要一个接口的实例并且只被调用一次,因此不需要为这个方法创建一个新类时,这可能很有帮助。

匿名接口实现

。NET 2.0也支持匿名委托,只是语法比lambdas更冗长,而且类型推断不起作用。而且在c# 2.0中没有扩展方法(尽管你可以使用c# 3.0并针对。net 2.0进行编译),这些扩展方法是LINQ的基础,并且能够在接口上进行操作。

比较:

  • 。Net 2.0: delegate(int i) { return (i < 5); }
  • 。净3.5: i => i < 5

。. NET 2.0也缺少通用的委托签名(FuncAction),但是您也可以自己定义它们(对于您喜欢的所有参数组合):

public delegate void Action<T>(T item);
public delegate Tresult Func<T, Tresult>(T item);

因此,无论您的链接答案采用什么方法来模拟匿名接口,都可以使用。net 2.0委托来表示,代价是增加冗长性。让你问自己:"这个真的比更短吗?"

(更新)

如果你的接口是一个单方法接口,如:

interface IFoo
{
    string Bar(int value);
}
class SomeOtherClass
{
    void DoSomething(IFoo foo);
}

,那么你可以完全摆脱它,简单地使用委托代替:

class SomeOtherClass
{
    void DoSomething(Func<int, string> bar);
}
new SomeOtherClass().DoSomething(delegate(int i) { return i.ToString(); });

如果你有一个包含许多方法的接口,你想在许多不同的地方实现内联,你可以使用这样的东西:

interface IFoo
{
    string GetSomething();
    void DoSomething(int value);
}
// conditional compile, only if .NET 2.0
#if NET_2_0
public delegate void Action<T>(T item);
public delegate Tresult Func<Tresult>();
#endif
class DelegatedFoo : IFoo
{
    private readonly Func<string> _get;
    private readonly Action<int> _do;
    public DelegatedFoo(Func<string> getStuff, Action<int> doStuff)
    {
        _get = getStuff;
        _do = doStuff;
    }
    #region IFoo members simply invoke private delegates
    public string GetSomething()
    { return _get(); }
    public void DoSomething(int value)
    { _do(value); }
    #endregion
}

这将允许您将委托传递给DelegatedFoo类inline:

var delegated = new DelegatedFoo(
    delegate() { return ""; }, // string GetSomething()
    delegate(int i) { }        // void DoSomething(int)
);
使用<<p>>。. NET 4 c# 4.0的语法,由于lambdas和命名参数的语法甜味,它将看起来更干净:
var delegated = new DelegatedFoo(
    getStuff: () => "",
    doStuff:  i => { }
);

我知道这可能不是您所希望的,但是如果您必须这样做,您可以使用任何可用的mock框架来请求实现接口的对象,然后为方法添加实现。这是TDD中的标准实践。

同样,你也可以按照John Skeet在你提到的问题中的建议,简单地使用匿名委托来实现你的大部分需求。