简体   繁体   English

从继承的类浅复制

[英]Shallow Copy From Inherited Classes

Ok so I have an abstract base class called Product, a KitItem class that inherits Product and a PackageKitItem class that inherits KitItem. 好的,我有一个名为Product的抽象基类,一个继承Product的KitItem类和一个继承KitItem的PackageKitItem类。 ie. 即。

Product
KitItem : Product
PackageKitItem : KitItem

I have my KitItems loaded and I need to load up a collection of PackageKitItems which are, effectively, shallow copies of KitItems. 我已经加载了KitItems,并且需要加载一个PackageKitItems集合,它们实际上是KitItems的浅表副本。

Currently we are doing what feels to me a hacky shallow copy in the Product constructor like so: 当前,我们正在做我感觉像是在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));
        }

I've tried setting up a copy on KitItem like so: 我试图像这样在KitItem上设置副本:

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

and calling it thus: 并这样称呼它:

PackageKitItem tempPackKitItem = (PackageKitItem)packKitItem.ShallowCopy();

but I get an invalid cast. 但是我得到一个无效的演员表。 I'm looking for ideas for the best way to accomplish this. 我正在寻找实现最佳方法的想法。

The problem you have is that since ShallowCopy() is a member of KitItem, MemberwiseClone() is just copying the KitItem fields and returning a KitItem even if the original object is a PackageKitItem. 您遇到的问题是,由于ShallowCopy()是KitItem的成员,所以MemberwiseClone()只是复制KitItem字段并返回KitItem,即使原始对象是PackageKitItem也是如此。

I think what you have to do in this circumstance add to KitItem: 我认为您在这种情况下必须做的事情添加到KitItem中:

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

and in PackageKitItem: 并在PackageKitItem中:

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

Thus you will get the proper MemberwiseClone() call done depending on the object you are trying to ShallowCopy(). 因此,根据要尝试ShallowCopy()的对象,您将获得正确的MemberwiseClone()调用。

If you wanted to go further, you could define a ShallowCopy() in Product (returning a Product) and then have overridden versions in KitItem and PackageKitItem each returning their respective shallow copy. 如果想走得更远,可以在Product中定义ShallowCopy()(返回一个产品),然后在KitItem和PackageKitItem中设置覆盖的版本,每个版本都返回各自的浅表副本。

Strangely I didn't get an error doing this on Visual Studio 2008. I am posting the code so you can see what I am missing or what I am assuming wrong. 奇怪的是,在Visual Studio 2008上执行此操作时没有出现错误。我正在发布代码,以便您可以看到丢失的内容或出现的错误。 My guess is that the problem is in one of the class members that you didn't post. 我的猜测是问题出在您未发布的班级成员之一中。

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;

}

In your Product constructor you are already doing some form of shallow copy, aren't you? 在您的Product构造函数中,您已经在进行某种形式的浅表复制,不是吗? If you haven't overwritten your constructor, then you should be able to just create a new PackageKitItem that receives a KitItem as its parameter. 如果您尚未覆盖构造函数,那么您应该能够创建一个新的PackageKitItem来接收KitItem作为其参数。

PackageKitItem tempPackKitItem = new tempPackKitItem(kitItem);

Maybe I just misunderstood your question. 也许我只是误解了你的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM