3

私がクラスを持っているとしましょう:

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

いくつかの関数では、オブジェクトタイプParentのリストを取得しています。次に、これらのオブジェクトを新しいフィールドで値を指定して拡張したいので、次のような拡張クラスを宣言します。

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

拡張オブジェクトごとにコストラクタを呼び出します。それを行うためのより良い方法はありますか?親に複数のプロパティがある場合はどうなりますか?たぶんそれを達成するためのよりエレガントな方法がありますか?

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 に答える