是的,但是在 C# 1.0 到 C# 7.3 中这很乏味...
C# 不像 C++ 那样支持隐式复制构造函数。您需要自己手动定义复制构造函数。
...是的,这既乏味又烦人。
类似这样的:
class PersonCommonData
{
public PersonCommonData(
Int32 personId,
String firstName,
String lastName,
Date dob
)
{
this.PersonId = personId;
this.FirstName = firstName;
this.LastName = lastName;
this.DoB = dob;
}
// Copy-constructor:
protected PersonCommonData( PersonCommonData copy )
: this(
personId: copy.PersonId,
firstName: copy.FirstName,
lastName: copy.LastName,
dob: copy.DoB
)
{
}
public Int32 PersonId { get; }
public String FirstName { get; }
public String LastName { get; }
public Date DoB { get; }
}
class EmployeePerson : PersonCommonData
{
public EmployeePerson( PersonCommonData copy, Int32 employeeId )
: base( copy )
{
this.EmployeeId = employeeId;
}
public Int32 EmployeeId { get; }
}
用法:
PersonCommonData common = GetCommonData( personId: 123 );
EmployeePerson e = new EmployeePerson( common, employeeId: 456 );
C# 7 更好的主意:组合
如果您改为组合派生类中的基本公共数据对象,那么这会简化事情:
(请注意,如果您的类是不可变的,这可能只是一个好主意,因为在对象图中拥有可变数据,甚至 可能是可变数据 很少是一个好主意 - 好消息是 C# 9.0 的 record 类型减少了很多乏味,尽管它们并没有消除它)。
class PersonCommonData
{
public PersonCommonData(
Int32 personId,
String firstName,
String lastName,
Date dob
)
{
this.PersonId = personId;
this.FirstName = firstName;
this.LastName = lastName;
this.DoB = dob;
}
public Int32 PersonId { get; }
public String FirstName { get; }
public String LastName { get; }
public Date DoB { get; }
}
class EmployeePerson
{
private readonly PersonCommonData common;
public EmployeePerson( PersonCommonData common, Int32 employeeId )
{
this.common = common ?? throw new ArgumentNullException(nameof(common));
this.EmployeeId = employeeId;
}
public Int32 EmployeeId { get; }
// Tedium: need to repeat every member as a property-forwarder:
public Int32 PersonId => this.common.PersonId;
public String FirstName => this.common.FirstName;
public String LastName => this.common.LastName;
public Date DoB => this.common.DoB;
}
在带有 record 类型和默认接口实现的 C# 9.0 中甚至更好......
如果您只使用不可变数据,那么在 C# 9.0 中,您可以使用 record 类型,从而消除很多乏味。不过,我觉得它们在作曲方面效果最好:
public record PersonCommonData(
Int32 PersonId,
String FirstName,
String LastName,
Date DoB
);
public interface IHasPersonCommonData
{
PersonCommonData Common { get; }
Int32 PersonId => this.Common.PersonId;
String FirstName => this.Common.FirstName;
String LastName => this.Common.LastName;
Date DoB => this.Common.DoB;
}
public interface IEmployeePerson : IHasPersonCommonData
{
Int32 EmployeeId { get; }
}
public record EmployeePerson(
PersonCommonData Common,
Int32 EmployeeId
) : IEmployeePerson;
public interface IStudentPerson : IHasPersonCommonData
{
Int32 StudentId { get; }
}
public partial StudentPerson( PersonCommonData Common, Int32 StudentId ) : IStudentPerson;
但有一些限制——C# 仍然不支持真正的 mixins(接口默认实现仅在通过接口访问类型时才起作用,成员不被继承boo)。