2

さて、Product という抽象基本クラス、Product を継承する KitItem クラス、および KitItem を継承する PackageKitItem クラスがあります。すなわち。

Product
KitItem : Product
PackageKitItem : KitItem

KitItems をロードしましたが、PackageKitItems のコレクションをロードする必要があります。これは、事実上、KitItems の浅いコピーです。

現在、次のように、 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();

しかし、私は無効なキャストを取得します。これを達成するための最良の方法のアイデアを探しています。

4

3 に答える 3

4

あなたが抱えている問題は、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() を定義して (Product を返す)、KitItem と PackageKitItem でバージョンをオーバーライドして、それぞれの浅いコピーを返すことができます。

于 2008-11-15T19:48:33.713 に答える
1

不思議なことに、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;

}
于 2008-11-12T14:08:06.437 に答える
0

Product コンストラクターでは、すでに何らかの形式の浅いコピーを行っていますよね? コンストラクターを上書きしていない場合は、パラメーターとして KitItem を受け取る新しい PackageKitItem を作成するだけでよいはずです。

PackageKitItem tempPackKitItem = new tempPackKitItem(kitItem);

多分私はあなたの質問を誤解しただけです。

于 2008-11-12T14:04:36.910 に答える