派生クラスに基底クラスの値をコピーするには

[code]

    public class A
    {
        public string Value1 { get; set; }
        public string Value2 { get; set; }
        ・・・
        public string Value100 { get; set; }
    }
    
    public class B : A
    {
        public B(A a)
        {
            this.Value1 = a.Value1;
            this.Value2 = a.Value2;
            ・・・
            this.Value100 = a.Value100;
        }
    }
    
[/code]

基底クラスが保持している値を派生クラスのインスタンスにコピーする簡潔な記述方法はあるでしょうか。  
上記のコードのように基底クラスに多くのプロパティ（またはフィールド）がある場合、単純にコピーロジックを書くと長くなってしまうので、もっと簡潔に書ける方法はないかと思い、質問しました。




条件さえ合えば以下のような方法もあります。

# シリアライズして復元

Aがシリアライズ可能であれば、シリアライズ化して復元する方法が使えます。

[code]

    void Test()
    {
        A a = new A();
        B b = B.Create(a);
    }
    
    [DataContract]
    public class A
    {
        [DataMember]
        public string Value1 { get; set; } = "A1";
        [DataMember]
        public string Value2 { get; set; } = "A2";
    }
    
    [DataContract]
    public class B : A
    {
        [DataMember]
        public string ValueB1 { get; set; } = "B1";
    
        public static B Create(A a)
        {
            using (var ms = new MemoryStream())
            {
                var serializerA = new DataContractSerializer(typeof(A));
                serializerA.WriteObject(ms, a);
                ms.Seek(0, SeekOrigin.Begin);
                var serializerB = new DataContractSerializer(typeof(B));
                var classB = (B)serializerB.ReadObject(ms);
                // classB.ValueB1 = "B1"; // TODO: デシリアライズではコンストラクタが実行されないので適時初期化
                return classB;
            }
        }
    }
    
    
[/code]

# クラスAのメソッドを拡張

メソッドを追加するだけであれば、クラスBの必要はなく、拡張メソッドで対応可能です。

[code]

    void Test()
    {
        A a = new A();
        a.Dump();
    }
    
    public static class ClassAExtensions
    {
        public static void Dump(this A self)
        {
            Debug.WriteLine(self.Value1 + self.Value2);
        }
    }
    
[/code]




条件さえ合えば以下のような方法もあります。

# シリアライズして復元

Aがシリアライズ可能であれば、シリアライズ化して復元する方法が使えます。

[code]

    void Test()
    {
        A a = new A();
        B b = B.Create(a);
    }
    
    [DataContract]
    public class A
    {
        [DataMember]
        public string Value1 { get; set; } = "A1";
        [DataMember]
        public string Value2 { get; set; } = "A2";
    }
    
    [DataContract]
    public class B : A
    {
        [DataMember]
        public string ValueB1 { get; set; } = "B1";
    
        public static B Create(A a)
        {
            using (var ms = new MemoryStream())
            {
                var serializerA = new DataContractSerializer(typeof(A));
                serializerA.WriteObject(ms, a);
                ms.Seek(0, SeekOrigin.Begin);
                var serializerB = new DataContractSerializer(typeof(B));
                var classB = (B)serializerB.ReadObject(ms);
                // classB.ValueB1 = "B1"; // TODO: デシリアライズではコンストラクタが実行されないので適時初期化
                return classB;
            }
        }
    }
    
    
[/code]

# クラスAのメソッドを拡張

メソッドを追加するだけであれば、クラスBの必要はなく、拡張メソッドで対応可能です。

[code]

    void Test()
    {
        A a = new A();
        a.Dump();
    }
    
    public static class ClassAExtensions
    {
        public static void Dump(this A self)
        {
            Debug.WriteLine(self.Value1 + self.Value2);
        }
    }
    
[/code]

