代码之家  ›  专栏  ›  技术社区  ›  Echostorm

继承类的浅拷贝

  •  2
  • Echostorm  · 技术社区  · 16 年前

    好的,我有一个名为product的抽象基类、一个继承product的KitItem类和一个继承KitItem的PackageKitItem类。IE.

    Product
    KitItem : Product
    PackageKitItem : KitItem
    

    我把我的风筝装上了,我需要装上一系列的PackageKittems,它们实际上是Kittems的浅拷贝。

    目前,我们正在做一个我觉得在产品构造中很简单的复制,就像这样:

    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 回复  |  直到 14 年前
        1
  •  4
  •   TAG    16 年前

    问题是,由于shallowcopy()是kitItem的成员,所以memberWiseClone()只是复制kitItem字段并返回kitItem,即使原始对象是packagekitItem。

    我认为在这种情况下,你必须做的是增加KitItem:

    public virtual KitItem ShallowCopy()        
    {            
      return (KitItem) this.MemberwiseClone();        
    }
    

    在PackageKittem中:

    public override KitItem ShallowCopy()        
    {            
        return (PackageKitItem) this.MemberwiseClone();        
    }
    

    因此,根据您尝试的对象shallowcopy(),您将完成正确的memberWiseClone()调用。

    如果您想更进一步,可以在产品(返回产品)中定义一个shallow copy(),然后在kitem和packagekitem中重写版本,每个版本都返回各自的shallow copy。

        2
  •  1
  •   RS Conley    16 年前

    奇怪的是,在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;
    
    }
    
        3
  •  0
  •   Leonardo Herrera    16 年前

    在你的产品构造中,你已经在做某种形式的肤浅复制了,不是吗?如果您还没有覆盖构造函数,那么您应该能够创建一个新的packagekittem,它接收一个kitem作为其参数。

    PackageKitItem tempPackKitItem = new tempPackKitItem(kitItem);
    

    也许我误解了你的问题。