継承されたクラスからの浅いコピー
-
08-07-2019 - |
質問
わかりましたので、Productという抽象基本クラス、Productを継承するKitItemクラス、およびKitItemを継承するPackageKitItemクラスがあります。すなわち。
Product
KitItem : Product
PackageKitItem : KitItem
KitItemがロードされており、事実上、KitItemの浅いコピーであるPackageKitItemのコレクションをロードする必要があります。
現在、Productコンストラクターでは、次のようにハッキングされた浅いコピーを感じています:
public Product(Product product)
{
FieldInfo[] fields = product.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
// copy each value over to 'this'
foreach (FieldInfo fi in fields)
fi.SetValue(this, fi.GetValue(product));
}
次のようにKitItemにコピーを設定しようとしました:
public KitItem ShallowCopy()
{
return (KitItem)this.MemberwiseClone();
}
そしてこのように呼び出す:
PackageKitItem tempPackKitItem = (PackageKitItem)packKitItem.ShallowCopy();
しかし、無効なキャストを受け取ります。これを達成するための最良の方法についてのアイデアを探しています。
解決
問題は、ShallowCopy()はKitItemのメンバーであるため、元のオブジェクトがPackageKitItemであっても、MemberwiseClone()はKitItemフィールドをコピーしてKitItemを返すだけです。
この状況であなたがしなければならないことはKitItemに追加すると思います:
public virtual KitItem ShallowCopy()
{
return (KitItem) this.MemberwiseClone();
}
およびPackageKitItem内:
public override KitItem ShallowCopy()
{
return (PackageKitItem) this.MemberwiseClone();
}
したがって、ShallowCopy()を試行しているオブジェクトに応じて、適切なMemberwiseClone()呼び出しが行われます。
さらに先に進みたい場合は、Product(製品を返す)でShallowCopy()を定義し、KitItemおよびPackageKitItemでそれぞれの浅いコピーを返すオーバーライドされたバージョンを持つことができます。
他のヒント
奇妙なことに、Visual Studio 2008でこれを実行してもエラーは発生しませんでした。コードを投稿しているので、不足しているものや間違っていると思われるものを確認できます。私の推測では、問題はあなたが投稿しなかったクラスメンバーの1つにあると思われます。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
PackageKitItem PKI = new PackageKitItem();
PKI.ID = 1;
PKI.KitName = "2";
PKI.Name = "3";
PKI.Package = 4;
PackageKitItem tempPackKitItem = (PackageKitItem)PKI.ShallowCopy();
}
}
}
public class Product
{
public int ID;
public string Name;
public Product()
{
}
public Product(Product product)
{
FieldInfo[] fields = product.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
// copy each value over to 'this'
foreach (FieldInfo fi in fields)
fi.SetValue(this, fi.GetValue(product));
}
}
public class KitItem:Product
{
public string KitName;
public KitItem ShallowCopy()
{
return (KitItem)this.MemberwiseClone();
}
}
public class PackageKitItem : KitItem
{
public int Package;
}
Productコンストラクターでは、すでに何らかの形式の浅いコピーを実行していますよね?コンストラクターを上書きしていない場合は、KitItemをパラメーターとして受け取る新しいPackageKitItemを作成するだけで済みます。
PackageKitItem tempPackKitItem = new tempPackKitItem(kitItem);
たぶん私はあなたの質問を誤解しただけかもしれません。