C#接口 - 使用不同的签名实现

时间:2011-06-03 15:34:39

标签: c# interface

我认为这也是一个设计问题。当覆盖签名具有不同的签名类型时,是否可以从接口覆盖方法?

例如,假设我想要两个应该具有以下内容的不同类:

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

是否可以阻止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) {}
 }

9 个答案:

答案 0 :(得分:3)

您的最后一个选项是唯一可行的选项(因为它是在两个类中正确实现接口的唯一选项)。

但请记住,通过界面访问该类的任何人都只能访问connect(Type1 t1, Type2 t2, Type3 t3)方法,这会完全阻止您提供另一个方法(除非人们也可以直接访问该类型)。< / p>

答案 1 :(得分:3)

接口是您的类'注册'的'合同',并且该类必须按照定义实现接口。第二种方法是使用扩展接口指定类的类特定方法然后调用接口方法是一种合理的解决方案,但当然这意味着您不能将接口用作可能会破坏目的的类型。

答案 2 :(得分:3)

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

答案 3 :(得分:1)

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

答案 4 :(得分:1)

我要么说选择2,要么改变接口以接受类型列表。

答案 5 :(得分: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);
    }

答案 6 :(得分:0)

如果您希望所有实现IProtocolClient的类都知道这两个签名,那么将过载签名添加到代理

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

如果你想在某些实现中隐藏该签名,你可以明确地实现它

    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实现了原始接口,然后添加了重载签名。但是,在这种情况下,任何将classB投射到IProtocolInterface的人都不会看到第二个签名。

答案 7 :(得分:0)

如果所有类型都相同,或者具有公共基类或接口,例如IConnectable, 你可以使用params关键字:

http://msdn.microsoft.com/en-us/library/w5zay9db.aspx

答案 8 :(得分:0)

如果将所有参数作为对象传递,则可以派生参数类,然后将其投射到实现的方法中。

    interface IProtocolClient
    {
        void connect(ParamType p);
    }

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

=&GT;

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

HTH