19

現在、派生クラスと基本クラスがあります。派生クラスの基本クラスを自分の基本クラスと同じにするにはどうすればよいですか? 浅いコピーは機能しますか?

class Base
{
    private string name; 
    public string Name { get; set; }
    private string address; 
    public string Address { get; set; }
}

class Derived:Base
{
    private string field; 
    public String field { get; set; }
}

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Base b = new Base();
            b.Address = "Iliff";
            b.Name = "somename"; 

            Derived d = new Derived();
            //How can I make the base class of d equal to b ?

        }
    }
}
4

10 に答える 10

20

基本クラスのコピー コンストラクターを作成します。その際、パラメーターのないコンストラクターも作成する必要があります。また、コピー コンストラクターを追加すると、既定のコンストラクターがコンパイラによって生成されなくなります。次に、派生クラスで、基本クラスのコピー コンストラクターを呼び出します。

public class Base
{
    public int Name { get; set; }
    public string Address { get; set; }

    public Base()
    { }

    public Base(Base toCopy)
    {
        this.Name = toCopy.Name;
        this.Address = toCopy.Address;
    }
}

public class Derived : Base
{
    public String Field { get; set; }

    public Derived(Base toCopy)
        : base (toCopy)
    { }

    // if desired you'll need a parameterless constructor here too
    // so you can instantiate Derived w/o needing an instance of Base
    public Derived()
    { }
}
于 2013-01-30T21:27:54.883 に答える
11

別のアプローチは、基本クラスを派生クラスにマップすることです。

/// <summary>
/// Maps the source object to target object.
/// </summary>
/// <typeparam name="T">Type of target object.</typeparam>
/// <typeparam name="TU">Type of source object.</typeparam>
/// <param name="target">Target object.</param>
/// <param name="source">Source object.</param>
/// <returns>Updated target object.</returns>
public static T Map<T, TU>(this T target, TU source)
{
    // get property list of the target object.
    // this is a reflection extension which simply gets properties (CanWrite = true).
    var tprops = target.GetProperties();

    tprops.Where(x=>x.CanWrite == true).ToList().ForEach(prop =>
    {
        // check whether source object has the the property
        var sp = source.GetType().GetProperty(prop);
        if (sp != null)
        {
            // if yes, copy the value to the matching property
            var value = sp.GetValue(source, null);
            target.GetType().GetProperty(prop).SetValue(target, value, null);
        }
    });

    return target;
}

例:

var derivedClass = new DerivedClass();
derivedClass.Map(baseClass);
于 2014-03-01T16:29:16.753 に答える
10

私があなたを正しく理解していれば、これはうまくいきます:

class Derived : Base
{
    // all the code you had above, plus this:

    public Derived(Base toCopy)
    {
        this.name = toCopy.name;
        this.address = toCopy.address;
    }
}

Derived d = new Derived(b);
于 2013-01-30T21:18:36.473 に答える
4

Baseインスタンスのフィールドを新しいインスタンスに手動でコピーする必要がありDerivedます。

これを行う一般的な方法は、コピー コンストラクターを提供することです。

public Derived(Base other)
{
    if (other == null) {
        throw new ArgumentNullException("other");
    }

    this.name = other.name;
    this.address = other.address;
}

コードに関するもう 1 つの注意事項:

private string field; 
public string Field { get; set; }

これはあまり意味がありません (他のプロパティも同様です)。

public string Field { get; set; }プライベート フィールドがコンパイラによって自動的に作成されることを意味します。あなたのfieldフィールドはまったく使用されません。

public string Field { get; set; }プライベートフィールドが自動的に作成されるため、どちらかを書くだけです。Fieldまたは、プライベート フィールドが使用されるようにプロパティを宣言します。

private string field;

public string Field {
    get {
        return field;
    }
    set {
        field = value;
    }
}
于 2013-01-30T21:17:33.670 に答える
1

この状況に対処するためのかなり良いパターンを思いつきました。

public class Base
{
    public int BaseField;

    /// <summary>
    /// Apply the state of the passed object to this object.       
    /// </summary>
    public virtual void ApplyState(Base obj)
    {
        BaseField = obj.BaseField;
    }
}

public class Derived : Base
{
    public int DerivedField;

    public override void ApplyState(Base obj)
    {
        var src = srcObj as Derived;

        if (src != null)
        {
            DerivedField = src.DerivedField;
        }

        base.ApplyState(srcObj);        
    }
}

タイプ「ベース」を共有する任意の 2 つのオブジェクトを指定すると、A を B に、または B を A に適用できます。

于 2016-02-24T01:16:22.977 に答える
1

いつでも Object.MemberwiseClone を使用してコピーできます。

http://msdn.microsoft.com/en-us/library/system.object.memberwiseclone.aspx

または、IClonable インターフェイスを実装します: http://msdn.microsoft.com/en-us/library/system.icloneable.aspx

于 2013-01-30T21:23:29.967 に答える
0

他のいくつかの回答がこのソリューションに触れている可能性があることを認識していますが、より完全に説明したかったのです。

私が見つけた解決策は、基本クラスを設定し、その基本クラスを派生クラスのコンストラクターに渡すことでした。派生クラスのコンストラクターは、基本クラスに基づいてそのフィールドに値を設定します。

class Base
{
    private string name; 
    public string Name { get; set; }
    private string address; 
    public string Address { get; set; }
}

class Derived:Base
{
    Derived(Base toCopy)
    {
        this.Name = toCopy.Name;
        this.Address = toCopy.Address;
    }

    private string field; 
    public String field { get; set; }
}

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Base b = new Base();
            b.Address = "Iliff";
            b.Name = "somename"; 

            //You are now passing the base class into the constructor of the derived class.
            Derived d = new Derived(b);


        }
    }
}
于 2016-07-06T17:04:53.290 に答える
-6

これを変更するだけです。

Derived d = (Derived)b;

また、名前のデータ型は int ではなく文字列にする必要があります

于 2013-01-30T21:16:26.310 に答える