[英]C# best partial interface implementation in base/abstract class
.net does not allow partial interface implementation in base classes. .net不允许在基类中实现部分接口。 As a mitigation I've come to 3 alternate solutions. 作为缓解措施,我已经提出了3种替代解决方案。 Please help me decide which is more universal in terms of refactoring, compile/run time errors, readability. 请帮我决定哪些在重构,编译/运行时错误,可读性方面更具普遍性。 But first a couple of comments. 但首先是几条评论。
My comparison: 我的比较:
public interface IFoo
{
void Method1();
void Method2();
}
public abstract class BaseClass1 : IFoo
{
void IFoo.Method1()
{
//some implementation
}
void IFoo.Method2()
{
IFooMethod2();
}
protected abstract void IFooMethod2();
}
public class MyClass1 : BaseClass1
{
[Obsolete("Prohibited direct call from child classes. only inteface implementation")]
protected override void IFooMethod2()
{
//some implementation
}
}
public abstract class BaseClass2 : IFoo
{
void IFoo.Method1()
{
//some implementation
}
[Obsolete("Prohibited direct call from child classes. only inteface implementation")]
public virtual void Method2()
{
throw new NotSupportedException();
}
}
public abstract class MyClass2 : BaseClass2
{
public override void Method2()
{
//some implementation
}
}
public abstract class BaseClass3 : IFoo
{
void IFoo.Method1()
{
//some implementation
}
void IFoo.Method2()
{
throw new NotSupportedException();
}
}
public abstract class MyClass3 : BaseClass3, IFoo
{
void IFoo.Method2()
{
//some implementation
}
}
I like this version, the base class can't be instantiated because its abstract, the derived class must list IFoo in its declaration or else it won't be implementing the interface and then it is solely responsible for implementing the rest of the interface. 我喜欢这个版本,基类不能实例化,因为它的抽象,派生类必须在其声明中列出IFoo,否则它将不会实现接口,然后它只负责实现接口的其余部分。 One drawback I can see is you can't explicitly implement the interface methods in the base class (ie no IFoo:Method1), but otherwise this is a fairly low overhead version. 我可以看到的一个缺点是你不能在基类中显式实现接口方法(即没有IFoo:Method1),但是否则这是一个相当低的开销版本。
public interface IFoo
{
void Method1();
void Method2();
}
public abstract class BaseClass1
{
public void Method1()
{
//some implementation
}
}
public class MyClass1 : BaseClass1, IFoo
{
public void Method2()
{
//some implementation
}
}
It is extremely bad to design a class that doesn't implement a well-defined contract. 设计一个没有实现明确定义的合同的类是非常糟糕的。 It is extreme because you firstly say that a class is capable of doing something. 这是极端的,因为你首先说一个班级能够做某事。 You explicitly highlight that the class can do stuff, but later in the code you say nahh, screw it, this class can live without implementation. 你明确地强调了类可以做的事情,但是后来在代码中你说nahh,拧紧它,这个类可以在没有实现的情况下生存。 Compiler very wisely asks you to implement the contract, but it is left up to you to decide. 编译器非常明智地要求您实施合同,但由您决定。
Here are some common solutions 这是一些常见的解决方案
Bad solution 解决方案不好
Better solution 好的解决方案
Best solution 最佳方案
Ok, you could try the following as BaseClass
is abstract: 好的,您可以尝试以下操作,因为BaseClass
是抽象的:
public interface IFoo
{
void Method1();
void Method2();
}
public abstract class BaseClass : IFoo
{
public void Method1()
{
// Common stuff for all BaseClassX classes
}
// Abstract method: it ensures IFoo is fully implemented
// by all classes that inherit from BaseClass, but doesn't provide
// any implementation right here.
public abstract void Method2();
}
public class MyClass1 : BaseClass
{
public override void Method2()
{
// Specific stuff for MyClass1
Console.WriteLine("Class1");
}
}
public class MyClass2 : BaseClass
{
public override void Method2()
{
// Specific stuff for MyClass2
Console.WriteLine("Class2");
}
}
private static void Main(string[] args)
{
IFoo test1 = new MyClass1();
IFoo test2 = new MyClass2();
test1.Method2();
test2.Method2();
Console.ReadKey();
}
I'd suggest having the abstract base class implement the interface with methods that call protected abstract
methods, as shown in your first example, except for methods which some derived classes may not implement (following the "throw everything into IList
but don't have all the methods actually work" pattern); 我建议让抽象基类使用调用protected abstract
方法的方法实现接口,如第一个示例所示,除了某些派生类可能无法实现的方法(在“将所有内容抛入IList
但没有所有方法实际上都是“模式”; those could be protected virtual
stubs which throw NotSupportedException
. 那些可能是protected virtual
存根,它会抛出NotSupportedException
。
Note that it is up to the child class whether to expose any particular member of the interface as a like-named public member (which could call the appropriate abstract member). 请注意,子类是否要将接口的任何特定成员公开为类似命名的公共成员(可以调用适当的抽象成员)。
The proper pattern in VB.net would be something like MustOverride Sub IFoo_Method1() Implements IFoo.Method1
, which would avoid the extra function call overhead, but C# doesn't provide any means of implementing an interface with a protected member. VB.net中的正确模式将类似于MustOverride Sub IFoo_Method1() Implements IFoo.Method1
,这将避免额外的函数调用开销,但C#不提供任何实现与受保护成员的接口的方法。 Using explicit interface implementation for any method which may have to be overridden in a child class is somewhat icky, because it's impossible for the child's re-implementation of the interface to chain to the parent's implementation. 对于可能必须在子类中重写的任何方法使用显式接口实现有点icky,因为子项的重新实现不可能链接到父实现。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.