向界面添加新功能

时间:2010-07-15 13:42:37

标签: c# interface overloading

我需要为现有接口上的函数创建重载,而不会影响当前实现或使用接口的任何组件(理想情况下)。

我想我有几个选择:

简化 原始界面:

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);
}

这种情况的最佳做法是什么?还有其他选择吗?

由于

6 个答案:

答案 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);