从继承的类浅复制

时间:2008-11-12 13:29:20

标签: c# inheritance shallow-copy

好的,我有一个名为Product的抽象基类,一个继承Product的KitItem类和一个继承KitItem的PackageKitItem类。即

Product
KitItem : Product
PackageKitItem : KitItem

我已经加载了我的KitItems,我需要加载一个PackageKitItems集合,它们实际上是KitItems的浅层副本。

目前我们在Product构造函数中做了一个hacky浅层副本,就像这样:

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();

但我得到了无效的演员。我正在寻找实现这一目标的最佳方法的想法。

3 个答案:

答案 0 :(得分: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中重写各自返回它们各自的浅拷贝。

答案 1 :(得分:1)

奇怪的是我在Visual Studio 2008上没有收到错误。我发布了代码,这样你就可以看到我缺少的东西或者我错误的东西。我的猜测是问题出在你没有发布的一个班级成员中。

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;

}

答案 2 :(得分:0)

在你的Product构造函数中,你已经在做某种形式的浅拷贝了,不是吗?如果你还没有覆盖你的构造函数,那么你应该能够创建一个接收KitItem作为参数的新PackageKitItem。

PackageKitItem tempPackKitItem = new tempPackKitItem(kitItem);

也许我只是误解了你的问题。