简体   繁体   English

C#:具有非抽象计算属性的多重继承

[英]C#: Multiple Inheritance with Non-Abstract Computed Properties

I'm creating a series of Interfaces/Abstract classes that contain basic properties and I would like to have computed Properties and multiple inheritance. 我正在创建一系列包含基本属性的Interfaces / Abstract类,我想要计算属性和多重继承。

public abstract class /interface Modifiable
{
   public DateTime ModifiedDate {get; set;}

   public boo ModifiedToday
   {
     get { return DateTime.Now.AddDays(-1).CompareTo(ModifiedDate) >= 0; }
   } 

   public bool ModifiedInLastWeek
   {
     get { return DateTime.Now.AddDays(-7).CompareTo(ModifiedDate) >= 0; }
   }
}

public abstract class /interface Deletable
{
   public DateTime DeletionDate {get; set;}    

   public bool Deleted
   {
     get { return DeletionDate != default(DateTime) }
   }
}

Then I have a class that inherits from these two Interfaces/Abstract classes. 然后我有一个继承自这两个Interfaces / Abstract类的类。

public class Something : Modifiable, Deletable 
{
  //
}

But a class cannot inherit from two abstract classes. 但是一个类不能从两个抽象类继承。 So I then need to use interfaces, but with interfaces I cannot have method bodies. 所以我需要使用接口,但是使用接口我不能拥有方法体。 I then have to define the same exact functions across multiple classes to implement these simple bool properties using interfaces. 然后我必须在多个类中定义相同的确切函数,以使用接口实现这些简单的bool属性。

I also don't want to have Modifiable inherit from Deletable because I might want something to be Modifiable but not Deletable. 我也不想从Deletable中获得可修改的继承,因为我可能想要一些可修改但不可删除的东西。 These specific classes aren't my problem, I'm simply using them to illustrate my problem. 这些特定的类不是我的问题,我只是用它们来说明我的问题。

Is there a design pattern that mimics an abstract class by allowing function bodies, but allows multiple inheritors like an interface? 是否存在通过允许函数体模仿抽象类的设计模式,但允许多个继承者如接口?

No. C# doesn't have a mechanism to implement multiple inheritance this way. 不,C#没有以这种方式实现多重继承的机制。

When it comes to interfaces, this is possible because when you define multiple interfaces you also need to implement them all. 说到接口,这是可能的,因为当你定义多个接口时,你还需要实现它们。

Consider a different design, possibly using composition in order to reuse the classes you want to use for multiple inheritance. 考虑一种不同的设计,可能使用组合来重用您想要用于多重继承的类。

It's not multiple inheritance, but something that comes to mind is Extension methods. 它不是多重继承,但我想到的是扩展方法。

public interface IModifiable
{
    DateTime ModifiedDate {get; set;}
}

public static class ModifiableExtensions
{
   public bool ModifiedToday(this IModifiable m)
   {
      return DateTime.Now.AddDays(-1).CompareTo(m.ModifiedDate) >= 0;
   } 

   public bool ModifiedInLastWeek(this IModifiable m)
   {
     return DateTime.Now.AddDays(-7).CompareTo(m.ModifiedDate) >= 0; 
   }

}

That gives the "feel" of helper methods that are baked into the type, but they happen to be declared elsewhere. 这给出了在类型中烘焙的辅助方法的“感觉”,但它们碰巧在其他地方声明。 Take this class: 上这堂课:

public class MyModifiable :IModifiable
{
     public ModifiedDate {get; set;}
}

And you can do this: 你可以这样做:

MyModifiable m = new MyModifiable;

m.ModifiedDate = DateTime.Now;

bool isToday = m.ModifiedToday();

Yes there are methods, several, actually. 是的,实际上有几种方法。 A few thoughts: 一些想法:

  • Use an empty interface for Deletable , Modifiable etc (called marker interfaces), then create extension methods for them. 使用空接口进行DeletableModifiable等(称为标记接口),然后为它们创建扩展方法。 This is not as expandable as multiple inheritance, but it gets a long way. 这不像多继承那样可扩展,但它有很长的路要走。
  • Use genericity, possibly with the same tagging interfaces to create dependencies. 使用通用性,可能使用相同的标记接口来创建依赖项。 This way you can have a base class with all methods for both Modifiable and Deletable, including abstract methods and override implementation in derived classes 这样,您就可以拥有一个基类,其中包含可修改和可删除的所有方法,包括派生类中的抽象方法和覆盖实现
  • Use aspect oriented programming to get to the same results 使用面向方面的编程来获得相同的结果
  • Almost the same, but do it yourself with Castle or similar library, possibly with the help of attributes. 几乎相同,但可以自己使用Castle或类似的库,可能借助属性。

Obviously, none of the above has all the advantages of multiple inheritance. 显然,以上都没有多重继承的所有优点。 If you want multiple inheritance in .NET, you can use C++.NET or Eiffel.NET. 如果要在.NET中进行多重继承,可以使用C ++。NET或Eiffel.NET。

I forget the design pattern name, but there's a pattern to implement multiple interfaces by wrapping the method/property calls around interface implementations of members who are of that same interface: 我忘记了设计模式名称,但是通过在同一接口的成员的接口实现周围包装方法/属性调用,有一种实现多个接口的模式:

interface IDrivable {
  void Drive();
}

interface IFlyable {
  void Fly();
}

class Car : IDrivable {
  public void Drive() { /* Implementation */ }
}

class Plane : IFlyable {
  public void Fly() { /* Implementation */ }
}

class MyClass : IDrivable, IFlyable {
  private IDrivable _car = new Car();
  private IFlyable _plane = new Plane();

  public void Drive() { _car.Drive(); }
  public void Fly() { _plane.Fly(); }
}

Sorry, multiple inheritance is not possible in C# and that's a bummer for you. 对不起,在C#中无法进行多重继承,这对你来说很无聊。 Your choices are: 你的选择是:

  1. Either to chain your base class inheritance a la MyClass : MyBaseClass : EvenBasierClass 要么将基类继承链接到MyClass:MyBaseClass:EvenBasierClass
  2. Or inherit from multiple interfaces. 或者从多个接口继承。 And implement all methods of all interfaces. 并实现所有接口的所有方法。

It's not pretty, but you can also control property accessibility or return values inside your classes by checking the instance type. 它不漂亮,但您也可以通过检查实例类型来控制属性可访问性或返回类中的值。

Modifiable & Deletable IMO should be interfaces, not base classes. 可修改和可删除的IMO应该是接口,而不是基类。 A base class defines what a type is, whereas a interface describes what a type does. 基类定义类型是什么,而接口描述类型的作用。

As far as implementing the code, you can always use extension methods: 至于实现代码,您始终可以使用扩展方法:

public interface IModifiable
{
   public DateTime ModifiedDate {get; set;}
}

public interface IDeletable
{
   public DateTime DeletionDate {get; set;}    
}


public static class SomeExtentions
{
    public static bool IsModifiedToday(this IModifiable modifiable)
    {
        return DateTime.Now.AddDays(-1).CompareTo(modifiable.ModifiedDate) >= 0;
    } 

    public static bool IsModifiedInLastWeek(this IModifiable modifiable)
    {
        return DateTime.Now.AddDays(-7).CompareTo(modifiable.ModifiedDate) >= 0;
    }   
    public static bool IsDeleted(this IDeletable deletable)
    {
        return deletable.DeletionDate != default(DateTime);
    }
}

I would probably use delegation to achieve this. 我可能会使用委托来实现这一目标。 Create Modifiable and Deletable as interfaces, then create implementations of those. 创建可修改和可删除的接口,然后创建它们的实现。 Give the Something class instances of these implementations. 给这些实现的Something类实例。 Here's an example for Deletable: 这是Deletable的一个例子:

public interface Deletable
{
  DateTime DeletionDate{get;set;}
  bool Deleted{get;}
}

public class DeletableImpl : Deletable
{
  public DateTime DeletionDate{get; set;}
  public bool Deleted{get {return DeletionDate != default(DateTime);}}
}
// Do the same thing with Modifiable and ModifiableImpl

public class Something : Deletable, Modifiable
{
  private Deletable _deletable = new DeletableImpl();
  private Modifiable _modifiable = new ModifiableImpl();
  public DateTime DeletionDate
  {
    get{return _deletable.DeletionDate;}
    set{_deletable.DeletionDate = value;}
  }
  public bool Deleted{get{return _deletable.Deleted;}}
  public DateTime ModifiedDate {
    // and so on as above
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM