3

假设我有一堂课:

public class Parent
{
    public string Name { get; set; }
    public string City { get; set; }
}

在某些函数中,我得到了父对象类型的列表,接下来我想用具有一些值的新字段来扩展这些对象,所以我声明了一个这样的扩展类:

public class Child : Parent
{
    public Child(Parent parent)
    {
        Name = parent.Name;
        City = parent.City;
    }
    public int Age { get; set; }
}

并为每个扩展对象调用构造函数。有没有更好的方法来做到这一点?如果 Parent 中有多个属性怎么办?也许有一些更优雅的方式来实现这一目标?

4

3 回答 3

4

我想也许你正在寻找一种复制构造器模式。每个级别定义一个protected复制相关属性的构造函数:

public class Parent
{
    public string Name { get; set; }
    public string City { get; set; }

    //normal constructor
    public Parent()
    {

    }

    protected Parent(Parent copy)
    {
        this.Name = copy.Name;
        this.City = copy.City;
    }
}

Child继承自Parent,将其传递给复制构造函数,然后根据需要附加其新值:

public class Child : Parent
{
    public string NewInfo { get; set; }

    public Child(Parent copy)
        : base(copy)
    {

    }
}

用法可能如下所示:

Parent parent = new Parent() { Name = "Name", City = "StackOverflow"};

Child child = new Child(parent) { NewInfo = "Something new!" };

Console.WriteLine(child.Name); //Name
Console.WriteLine(child.City); //StackOverflow
Console.WriteLine(child.NewInfo); //Something new!

这样做的好处是您可以拥有多个继承级别,每个级别都管理自己的属性。

编辑:鉴于您最近的评论:

这个问题的动机是我得到一个包含数据的对象列表,并且想要显示这些数据但有一些额外的字段,而不涉及基类。

也许更好的方法是包装基类:

public class Child
{
    private readonly Parent WrappedParent;

    public string NewInfo { get; set; }

    public string Name 
    { 
        get { return WrappedParent.Name; }
        set { WrappedParent.Name = value; }
    }

    public string City 
    { 
        get { return WrappedParent.City; }
        set { WrappedParent.City = value; }
    }

    public Child(Parent wrappedParent)
    {
        this.WrappedParent = wrappedParent; 
    }
}

缺点是您必须重新声明每个属性,并且您不再继承 (不能被视为 a) "Parent",但是您肯定不再“接触”基类。如果这对您更好,可以将“父”属性移动到IParent接口中,但再次这样做是“接触”基类,因为您必须将IParent接口声明添加到其类定义中。

于 2013-02-19T18:58:18.000 回答
2

不知道我是否弄错了,但这可能是一个更标准的解决方案

public class Parent
{
    public Parent(string name, string city)
    {
       Name = name;
       City = city;
    }

    public string Name { get; set; }
    public string City { get; set; }
}

public class Child : Parent
{
    public Child(string name, string city, int age) : base(name, city)
    {
       Age = age;
    }
    public int Age { get; set; }
} 
于 2013-02-19T18:47:54.997 回答
0

你可以这样做

public class Parent
{
    public string Name { get; set; }
    public string City { get; set; }

    public Parent(string name, string city)
    {
        this.Name = name;
        this.City = city;
    }

    public Parent():this(string.Empty, string.Empty)
    {
    }
}

public class Child : Parent
{
    public Child(Parent parent, int age):base(parent.Name, parent.City)
    {
        this.Age = age;
    }

    public int Age { get; set; }
}
于 2013-02-19T18:49:22.753 回答