C#实现了不同的签名
本文关键字:实现 | 更新日期: 2023-09-27 17:58:24
我想这也是一个设计问题。当重写签名具有不同的签名类型时,是否可以从接口重写方法?
例如,假设我想要两个不同的类,它们应该具有以下内容:
interface IProtocolClient
{
void connect(Type1 t1, Type2 t2, Type3 t3);
}
是否有可能阻止种族间的竞争,但有一个不同的参数集?
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) {}
}
接口是类"签署"的"契约",该类必须实现定义的接口。您的第二种方法是使用特定于类的方法来扩展接口指定的类,然后调用接口方法,这是一个合理的解决方案,但这当然意味着您不能将接口用作可能无法达到目的的类型。
您的最后一个选项是唯一可能工作的选项(因为它是唯一一个在两个类中正确实现接口的选项)。
不过,请记住,任何通过接口访问类的人都只能访问connect(Type1 t1, Type2 t2, Type3 t3)
方法,这完全消除了您提供其他方法的事实(除非人们也可以直接访问该类型)。
如果你实现了一个接口,你必须包括任何方法、属性等。这就是接口的意义:它们是代码契约。这并不能阻止您使用不同的参数签名重载方法。但是,如果您不需要实现指定的方法,那么您可能根本不需要接口。
我认为要么使用选项2,要么更改接口以接受类型列表。
遗憾的是,如果您没有完全实现接口,编译会对您大发雷霆。
然而,我认为下面的实现非常干净。
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);
}
如果您希望实现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
的人都不会看到第二个签名。
如果所有类型都相同,或者有一个公共基类或接口,如IConnectable,你可以使用params关键字:
http://msdn.microsoft.com/en-us/library/w5zay9db.aspx
如果将所有参数作为对象传递,则可以派生参数类,然后在实现的方法中强制转换它。
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; }
}
hth