Search code examples
c#inheritanceshallow-copy

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. 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.

Currently we are doing what feels to me a hacky shallow copy in the Product constructor like so:

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:

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.


Solution

  • 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.

    I think what you have to do in this circumstance add to KitItem:

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

    and in 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().

    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.