我需要为现有接口上的函数创建重载,而不会影响当前实现或使用接口的任何组件(理想情况下)。
我想我有几个选择:
简化 原始界面:
public interface IServerComponent
{
bool Add(int a, int b);
}
我可以将新的重载函数添加到接口,并强制实现接口的每个类实现新函数。
public interface IServerComponent
{
bool Add(int a, int b);
bool Add(int a, int b, int c);
}
或者我可以创建一个实现原始界面的新界面。然后,其他使用原始类的类将不需要更改,任何新类都可以实现新接口...
public interface IServerComponent2 : IServerComponent
{
bool Add(int a, int b, int c);
}
这种情况的最佳做法是什么?还有其他选择吗?
由于
答案 0 :(得分:11)
如果新方法可以用旧方法表示,则可以使用扩展方法:
// Original interface
public interface IServerComponent
{
bool Add(int a, int b, int c);
}
// New overload
public static class MyServerMethods
{
public static bool Add(this IServerComponent component, int a, int b)
{
return component.Add(a, b, 0);
}
}
如果方法不能这样表达(即,它们确实需要由组件本身实现),那么我建议定义一个新接口。这种方法具有最大的向后兼容性。
答案 1 :(得分:4)
如果您的IServerComponent接口尚未发布,或者是仅由您自己的类实现的内部接口,并且新接口成员对实现该接口的所有现有类都有意义,请更改现有接口。
否则,创建一个扩展IServerComponent的IServerComponent2接口。 IIRC这是框架设计指南推荐的内容。可以在.NET Framework中以X509Certificate2类的形式找到此示例。
但是,如果新成员可以按原始成员实施,您也可以使用extension methods:
public interface IServerComponent
{
bool Add(int a, int b);
}
public static class ServerComponentExtensions
{
public static bool Add(this IServerComponent isc, int a, int b, int c)
{
return isc.Add(a, b) && isc.Add(b, c) && isc.Add(c, a);
}
}
答案 2 :(得分:1)
我意识到你的例子是做作的,但我想给你一个与你所表达的不同的人为的答案,以便你可以用不同的方式思考它。
,而不是让你的界面方法对具体事物进行操作,而不是让它变得有意义。例如
public interface IAddableThings
{
int a;
int b;
}
public interface IOtherAddableThings : IAddableThings
{
int a;
int b;
}
public interface IServerComponent
{
bool Add(IAddableThings things);
}
如果这真的是Add,那么我认为这更有意义,但如果它更像是Calculate(),那么你会想要将部分或全部方法操作向下移动到IAddableThings对象。 / p>
public interface IAddableThings
{
int a;
int b;
bool CalculateMe();
}
答案 3 :(得分:0)
它取决于上下文 - 如果有许多类实现原始接口,或者如果它已发布,那么唯一可行的方法是引入新的接口。另一方面,从长远来看,只有一个界面更清洁,所以如果你负担得起,我会说重构现有界面。
答案 4 :(得分:0)
如果您不需要或想要更改已经实现旧接口的类(现在或将来),您应该只创建第二个接口。但是,它感觉更像是一个黑客,可能会给你不那么直观的代码。
另外,根据我的经验,推迟重构从来都不是一个好主意。因此,如果您怀疑以后需要实现该接口,那么您可能只需更改现有接口并让自己不必担心。它绝对是更清洁的方式。
答案 5 :(得分:0)
我认为维护单个界面更容易,但第二种方法更好,因为不是每个类都需要实现bool Add(int a, int b, int c);