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.
-
In your Product constructor you are already doing some form of shallow copy, aren't you? 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 tempPackKitItem = new tempPackKitItem(kitItem);
Maybe I just misunderstood your question.
-
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. 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; }
-
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.
0 comments:
Post a Comment