C#:具有非抽象计算属性的多重继承
我正在创建一系列包含基本属性的接口/抽象类,我希望具有计算属性和多重继承C#:具有非抽象计算属性的多重继承,c#,inheritance,abstract-class,C#,Inheritance,Abstract Class,我正在创建一系列包含基本属性的接口/抽象类,我希望具有计算属性和多重继承 public abstract class /interface Modifiable { public DateTime ModifiedDate {get; set;} public boo ModifiedToday { get { return DateTime.Now.AddDays(-1).CompareTo(ModifiedDate) >= 0; } } p
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) }
}
}
然后我有一个从这两个接口/抽象类继承的类
public class Something : Modifiable, Deletable
{
//
}
但是一个类不能从两个抽象类继承。所以我需要使用接口,但是对于接口,我不能有方法体。然后,我必须在多个类中定义相同的精确函数,以使用接口实现这些简单的bool属性
我也不想让Modifiable从Deletable继承,因为我可能希望某些东西是可修改的,但不是可删除的。这些特定的类不是我的问题,我只是用它们来说明我的问题
是否有一种设计模式通过允许函数体来模拟抽象类,但允许多个继承者(如接口) 没有。C#没有一种机制以这种方式实现多重继承
当涉及到接口时,这是可能的,因为当您定义多个接口时,您还需要实现所有接口
考虑一种不同的设计,可能是使用组合来重用要用于多重继承的类。对不起,多重继承在C#中是不可能的,这对您来说是个麻烦。你的选择是:
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) }
}
}
这并不漂亮,但您也可以通过检查实例类型来控制类内的属性可访问性或返回值。这不是多重继承,而是扩展方法
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;
}
}
这给了被烘焙到类型中的助手方法的“感觉”,但它们恰好在其他地方声明。参加本课程:
public class MyModifiable :IModifiable
{
public ModifiedDate {get; set;}
}
你可以这样做:
MyModifiable m = new MyModifiable;
m.ModifiedDate = DateTime.Now;
bool isToday = m.ModifiedToday();
可修改和可删除IMO应该是接口,而不是基类。基类定义类型,而接口描述类型的功能 就实现代码而言,您始终可以使用扩展方法:
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);
}
}
我可能会利用授权来实现这一点。创建可修改和可删除的接口,然后创建这些接口的实现。给出这些实现的
Something
类实例。以下是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
}
是的,其实有很多方法。一些想法:
- 为
、Deletable
等(称为标记接口)使用空接口,然后为它们创建扩展方法。这不像多重继承那样可扩展,但它还有很长的路要走Modifiable
- 使用泛型,可能使用相同的标记接口来创建依赖项。这样,您就可以拥有一个基类,其中包含可修改和可删除的所有方法,包括派生类中的抽象方法和重写实现
- 使用面向方面的编程来获得相同的结果
- 几乎相同,但您可以使用Castle或类似的库来完成,可能需要借助属性
显然,以上这些都没有多重继承的所有优点。如果您想在.NET中使用多重继承,可以使用C++ .NET或Effel.net .< /P> < p>我忘记了设计模式名称,但是有一种模式,通过在相同接口的成员接口实现中封装方法/属性调用来实现多个接口:
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(); }
}
要是我想到那件事就好了@rqdq我看到您发布了几乎完全相同的代码解决方案,但是我的答案的第一行是我没有删除它的原因。我同意Interfaces的评论。扩展方法是主观的,我不会使用它们,因为您有能力修改类。当您不能直接修改类时,扩展方法是最好的。扩展方法破坏了封装,加上您已从对象本身删除了计算属性,从而防止子类重写其行为。这与您的问题没有直接关系,但只有几条注释:1。您可能想改用
DateTime?
(可为空的DateTime),然后可以执行DeletionDate!=null
而不是返回删除日期!=默认值(日期时间)
。2.将“I”放在接口名称之前是一种C#约定,因此您需要IModifiable
和IDeletable
。