如何在不修改的情况下扩展.net接口?

时间:2017-02-28 17:08:03

标签: c# .net vb.net

我首先要说的是,我不是一个专业的开发人员,但有大量的代码供各公司使用,主要用.net c#和vb编写。

话虽如此,我从来没有觉得需要扩展现有的类和接口,而且我现在有点挣扎,我想这样做,这是一个例子:

  1. 我在另一个应用程序的项目中添加了一个COM引用(无法编辑)。

  2. 这个引用有一个我想扩展的接口,例如_CellObject,我想为它添加一些方法。在过去,我会构建自己的类来处理这个问题,但是我认为更合适的方法是扩展它。

  3. 所以我构建了另一个接口,继承自_CellObject并添加我的新方法。

  4. 然后我构建了一个实现该接口的类,这是我意识到我做错了的地方,必须添加原始接口的所有方法,但我不想这样做。这就像我在某个地方错过了“部分”,或者这可能是不可能的?

  5. 有人能把我推向正确的方向吗?

6 个答案:

答案 0 :(得分:1)

这是真的。如果通过继承接口来扩展接口,那么当您实现从新接口继承的类时,您将需要实现接口中的所有方法以及它继承的接口。从某种意义上说,这有点是让新界面继承现有界面。否则,您可以创建一个新接口,而不是从现有接口继承。

答案 1 :(得分:1)

COM对象不支持实现继承或多态,因此不会有任何受保护的成员要覆盖。我通常不会看到开发人员尝试扩展COM对象。如果您需要添加相关功能,可以将其包装(composition over inheritance),也可以编写扩展方法。

答案 2 :(得分:0)

有两种扩展接口而不修改它的方法。首先创建从该接口继承的antoher接口。想象一下,你有Interface A,你想扩展它。

   interface A
{
    void SomeMethodA();
}

 interface B :A
{
    void SomeMethodB();
}

其次,您可以直接实现该界面。

   class C : A
   {
    public void SomeMethodA()
     {
        //your actual implementation
     }
   }

答案 3 :(得分:0)

一个选项(不包括COM的问题)是创建一个新的接口和类,其中包含旧版本的功能。现在,您的新类可以继承原始类,在使用新接口扩展它时保持其功能。

public interface _CellObject 
{
    void DoSomething();
}

public interface _CellObject2 : _CellObject 
{
    void DoSomethingElse();
}


public class CellObject : _CellObject 
{
    public void DoSomething()
    {
    }
}


public class CellObject2 : CellObject, _CellObject2 
{
    public void DoSomethingElse()
    {
        DoSomething();
    }
}

答案 4 :(得分:0)

只需从现有界面扩展另一个界面,这称为界面隔离。

public interface IContract
{
    void DoSomething();
}

public interface IContractChanged:IContract
{
    void DoSomethingMore();
}

现在您可以实施新合同IContractChanged以满足您的需求。

答案 5 :(得分:0)

您的第四点使我假设您具有要在新接口中重用的现有接口的一些默认实现。正如其他人已经提到的那样,您可以通过继承扩展现有接口。但是,您还需要在实现新接口的类中实现“旧”方法。

如果要在新类中重复使用default-implementaion,可以将其提供给其构造函数。因此,您有以下代码:

interface IBase 
{ 
    void DoSomething(); 
}
interface IDerived : IBase
{ 
    void SoSomethingMore(); 
}

class MyBase : IBase 
{ 
    public void DoSomething() { ... } 
}
class MyDerived : IDerived
{
    private readonly MyBase _m;
    public MyDerived(MyBase m) { this._m = m; }

    // now you only need to forward the call for the existing interface to the injected base-class
    public void DoSomething() => this._m.DoSomething();
    public void DoSomethingMore() => ...
}