2011-06-03 31 views
2

我想这也是一个设计问题。当重写签名具有不同的签名类型时,是否可以从接口覆盖方法?C#接口 - 具有不同签名的工具

例如,让我们说,我想应该有两个不同的类以下内容:

interface IProtocolClient 
{ 
    void connect(Type1 t1, Type2 t2, Type3 t3); 
} 

有没有可能到impelemt的interfrace,但有不同的参数吗?

class A : IProtocolClient { 
    public void connect(Type1 t1, Type2 t2, Type3 t3) {} 
} 

class B : IProtocolClient { 
    public void connect(Type1 t1, Type2 t2, Type3 t3, Type4 t4) {} 
} 

或者我应该接近这个通过创建一个基类来代替,然后创建类B中的包装方法,如:

class B : IProtocolClient { 
    public void connect(Type1 t1, Type2 t2, Type3 t3, Type4 t4) 
    { 
     // do what is needed with t4 to customize and then ... 
     connect(t1,t2,t3); 
    } 

    public void connect(Type1 t1, Type2 t2, Type3 t3) {} 
} 

回答

3

一个接口是一个'契约',你的类'签署',并且类必须实现接口的定义。第二种方法使用扩展接口指定类的类特定方法,然后调用接口方法是一个合理的解决方案,但当然意味着您不能将接口用作可能无法达到目的的类型。

1

如果您实现一个接口,你必须包括任何方法,属性等。这就是接口的要点:它们是代码契约。这并不妨碍您使用不同的参数签名重载方法。但是如果你不需要实现指定的方法,那么你可能根本不需要接口。

1

我想说要么与选项2或更改接口接受类型列表。

+0

他们应该使用仿制药,而不是名单,如果这就是你所建议。 – jlafay 2011-06-03 15:39:12

+0

是的很多 – 2011-06-03 16:07:31

2

您的最后一个选项是唯一可能工作的选项(因为它是在这两个类中正确实现接口的唯一选项)。但是,请记住,任何通过界面访问该类的人都只能访问connect(Type1 t1, Type2 t2, Type3 t3)方法,这完全破坏了您提供其他方面的事实(除非人们也可以直接访问该类型)。

3

不,这不是重载,它是超载。重载永不会覆盖,你必须实现原始的,然后提供一个调用接口实现的重载。

+0

良好的捕获和澄清。 – mdisibio 2011-06-03 15:50:06

0

很遗憾,如果你没有完全实现这个接口,编译就会吠叫你。

但是,我认为下面的实现很干净。

public interface ITestClass 
{ 
    void Test(Type a, Type b); 
} 

public class TestClass : ITestClass 
{ 

    //implement the interface here 
    public void Test(Type a, Type b) 
    { 
     Test(a, b); 
    } 

    //you actual implementation here 
    public void Test(Type a, Type b, Type c = null) 
    { 
     //implementation 
    } 
} 

更新 如果你用的事情列出来,然后这个实现是首选要:

public void Test(params Type[] parameters) 
    { 
     //sample usage 
     Type one, two, three, four; 
     Test(one, two); 
     Test(one, two, three, four); 
    } 
0

如果你想实现这一切IProtocolClient类有两个签名的知识,那么将过载签名添加到代理

public interface IProtocolClient 
{ 
    void connect(Type1 t1, Type2 t2, Type3 t3); 
    void connect(Type1 t1, Type2 t2, Type3 t3, Type4 t4) 
} 

如果要隐藏该Signa TURE在一些实现,可以实现它明确

class A : IProtocolClient { 
     public void connect(Type1 t1, Type2 t2, Type3 t3) {} 
     void IProtocolClient.connect(Type1 t1, Type2 t2, Type3 t3, Type4 t4){ 
     throw new NotImplementedException(); 
     }  
} 

但是如果你只需要在一个实例类范围内扩展的签名,那么你的最后一个例子是正确的,在classB实现原来的接口,然后添加过载签名。然而,在这种情况下,任何铸造classBIProtocolInterface的人都不会看到第二个签名。

0

,您可以派生参数类,然后将其转换为您实施的方法。

interface IProtocolClient 
    { 
     void connect(ParamType p); 
    } 

    class ParamType 
    { 
     public Type1 t1 { get; set; } 
     public Type2 t2 { get; set; } 
     public Type3 t3 { get; set; } 
    } 

=>

class A : IProtocolClient 
    { 
     public void connect(ParamType p) 
     { 
      //do something with p.t1, p.t2, p.t3 
     } 
    } 

    class B : IProtocolClient 
    { 
     public void connect(ParamType p) 
     { 
      var p2 = p as DerivedParamType; 
      if (p2 == null) 
       throw new ApplicationException("p must be of type DerivedParamType"); 
      //do something with p2.t1, p2.t2, p2.t3, p2.t4 
     } 
    } 

    class DerivedParamType : ParamType 
    { 
     public Type4 t4 { get; set; } 
    } 

心连心

相关问题