C# 继承:派生类中的派生属性

C# 继承:派生类中的派生属性,c#,inheritance,abstract-class,C#,Inheritance,Abstract Class,我正试图找出处理派生类的最佳方法,该派生类中还包含我希望从其他类派生的属性。让我向您展示简化类: public abstract class AttendanceEvent { public int Id { get; set; } public DateTime StartDateTime { get; set; } public DateTime EndDateTime { get; set; } public AttendanceCode

我正试图找出处理派生类的最佳方法,该派生类中还包含我希望从其他类派生的属性。让我向您展示简化类:

public abstract class AttendanceEvent  
{  
    public int Id { get; set; }  
    public DateTime StartDateTime { get; set; }  
    public DateTime EndDateTime { get; set; }  
    public AttendanceCode AttendanceCode { get; set; }  
}   

public abstract class AttendanceCode  
{  
    public int Id { get; set; }  
    public string Name { get; set; }  
    public string Code { get; set; }  
    public AttendanceType Type { get; set; }  
}  
现在我想做的是能够:

public class PublicAttendanceCode : AttendanceCode {}  
public class PublicLeave : AttendanceEvent 
{  
    // PublicAttendanceCode takes the place of AttendanceCode  
    public PublicAttendanceCode AttendanceCode { get; set; }  
}  
以及:

我考虑过使用泛型,所以我会:

public abstract AttendanceEvent<T> where T : AttendanceCode 

我想知道处理这种情况的推荐方法是什么,您认为使用这种或那种方法有什么缺陷吗?

您的设计没有冲突。
AttendanceEvent
的每个具体实现只包含一个
AttendanceCode
的具体实现
PublicLeave
始终w/
PublicAttendanceCode
PrivateLeave
始终w/
PrivateAttendanceCode

只要适当地编写函数体,一切都会好起来的

每当您为
PublicLeave
实例化或传入
AttendanceCode
时,请确保它是
PublicAttendanceCode
。同样,无论何时为
PublicLeave
实例化或传递
AttendanceCode
时,请确保它是
PrivateAttendanceCode

您的构造函数示例看起来很好。在它的主体中,但类似于

public PubliLeave(PublicAttendanceCode code, DateTime startDateTime, DateTime endDateTime)      
{ 
    AttendanceCode = code; 
    StartDateTime = startDateTime; EndDateTime = endDateTime;
}  

我唯一的建议是你改变一些名字,太多的名字看起来很像。(例如,将参数设置为上述构造函数
sDateTimeIn、eDateTimeIn
或其他类型,并将
AttendanceCode
成员命名为
myCode
,而不是将其与类的名称相同)

我想说的是,不要向派生类添加额外的属性,只需继续使用现有的AttendanceCode属性。我的直觉是你在做你正在做的事情时违反了LSP。
public class PublicLeave : AttendanceEvent
{
    public PubliLeave(PublicAttendanceCode code, DateTime startDateTime, DateTime endDateTime)
    {
        //more code here
    }
}
public PubliLeave(PublicAttendanceCode code, DateTime startDateTime, DateTime endDateTime)      
{ 
    AttendanceCode = code; 
    StartDateTime = startDateTime; EndDateTime = endDateTime;
}