实现除抽象基类之外的常见行为?

在C#中,我有一个类层次结构,顶部附近有几个抽象基类,并且有相当多的派生类。 这些具体类中的一些具有一些相同实现的共同属性和方法。 它让我感到浪费,因此一个解决方案可能是在另一个抽象基类中实现这种常见行为。

abstract class Control; abstract class SquareControl: Control { public int SquarishProperty; public void SquarishMethod(); }; class Window: SquareControl; class Button: SquareControl; 

但是,如果层次结构中的其他几个类共享某些其他行为,但是与另一个基类中的一个控件共享某些内容,该怎么办? 也许有很多共同点。 使用抽象基类实现对它进行建模是不切实际的吗?

 abstract class FlashableControl: Control { public int FlashyProperty; public void FlashMethod(); }; class StatusBar: FlashableControl; // but it's also a bit square too, hmm... 

那么如何在不使用基类的情况下跨类共享这样的实现呢?

我想我想将接口的实现委托给另一个类,并让该类代表所需的类实现这些属性和方法,这样对于用户来说,StatusBar和Window似乎支持标准接口,但是在涵盖它是实现它的其他东西。

我可以想象实现这种行为的聚合类,但这是否恰当,是否有任何陷阱? 有哪些替代方案?

谢谢

你可以使用这样的模式:

 public interface ICommonServices { string SomeProperty { get; set; } void SomeMethod(string param); } public static class CommonServiceMethods { public static void DoSomething(this ICommonServices services, string param) { services.SomeMethod(services.SomeProperty + ": " + param + " something extra!"); } } 

现在,所有实现ICommonServices的类也通过扩展方法获得一些自由行为,扩展方法仅依赖于所有ICommonServices实现者公开的那些function。 如果需要访问基类function,可以将其放在自己的接口中,并让ICommonServices也实现该接口。 现在,您可以为接口创建“默认”扩展function,而无需使用多个基类。


编辑

如果您希望其中一些方法是内部的,您可以像这样修改模式:

 public class MyObject : IServices { public string PublicProperty { get; private set; } string IServices.SomeProperty { get; set; } void IServices.SomeMethod(string param) { //Do something... } } public interface IPublicServices { string PublicProperty { get; } } internal interface IServices : IPublicServices { string SomeProperty { get; set; } void SomeMethod(string param); } internal static class ServiceMethods { public static void DoSomething(this IServices services, string param) { services.SomeMethod(services.SomeProperty + ": " + param + " something extra!"); } } 

基本上我们暴露了公共和内部接口。 请注意,我们显式实现了内部接口方法,因此这些方法不可用于公共消费(因为公共客户端无法访问接口类型。)在这种情况下,帮助程序扩展方法是内部的,依赖于内部接口,但您也可以创建依赖公共接口的公共帮助方法。

您可以使用’has-a’而不是’is-a’并委托给内部方形控件

  class Window : Control, ISquareControl { private SquareControl square; public void SquareOperation() { square.SquareOperation(); } } class SquareControl : Control, ISquareControl { public void SquareOperation() { // ... } } 

一种方法是使用接口和基类。

Flashable会成为一个好的界面而不是一个类。