我已经阅读了'C# anonymously implement interface (or abstract class)'线程,用于匿名实现接口。但我想知道使用.NET 2.0(NO LINQ)使用委托或任何类似的方法是否也可以。我从JAVA了解到以下可能:
MyClass m = MyMethod(new MyInterface() {
@override
public void doSomething() {...}
}
(我希望我记得很清楚,就在不久之前我使用过JAVA,但我想这是类似的东西)。当方法需要接口的实例并且只调用一次时,这可能会有所帮助,因此不需要为此单个方法创建新类。
答案 0 :(得分:1)
.NET 2.0也支持匿名委托,只是语法比lambdas更冗长,类型推断不起作用。并且在C#2.0中没有扩展方法(尽管您可以使用C#3.0并针对.NET 2.0进行编译),这是LINQ的基础并且能够在接口上运行。
比较
delegate(int i) { return (i < 5); }
i => i < 5
.NET 2.0也缺少常见的通用委托签名(Func
和Action
),但您也可以自己轻松定义它们(对于您喜欢的所有参数组合):
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
类:
var delegated = new DelegatedFoo(
delegate() { return ""; }, // string GetSomething()
delegate(int i) { } // void DoSomething(int)
);
使用 .NET 4 C#4.0语法,由于lambdas和命名参数的语法甜度,它看起来会更清晰:
var delegated = new DelegatedFoo(
getStuff: () => "",
doStuff: i => { }
);
答案 1 :(得分:0)
我知道这可能不是您所希望的,但如果您必须这样做,您可以使用任何可用的模拟框架来请求实现该接口的对象,然后为这些方法添加实现。这是TDD的标准做法。
此外,您可以根据John Skeet在您提到的问题中的建议,使用匿名代表来满足您的大部分需求。