Малая копия из унаследованных классов
-
08-07-2019 - |
Вопрос
Хорошо, у меня есть абстрактный базовый класс Product, класс KitItem, который наследует Product, и класс PackageKitItem, который наследует KitItem. то есть.
Product
KitItem : Product
PackageKitItem : KitItem
У меня загружены мои KitItems, и мне нужно загрузить коллекцию PackageKitItems, которые, по сути, являются полными копиями KitItems.
В настоящее время мы делаем то, что мне кажется хакерской мелкой копией в конструкторе 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));
}
Я попытался настроить копию на KitItem следующим образом:
public KitItem ShallowCopy()
{
return (KitItem)this.MemberwiseClone();
}
и называем это так:
PackageKitItem tempPackKitItem = (PackageKitItem)packKitItem.ShallowCopy();
но я получаю неверный актерский состав. Я ищу идеи для лучшего способа сделать это.
Решение
Проблема в том, что поскольку ShallowCopy () является членом KitItem, MemberwiseClone () просто копирует поля KitItem и возвращает KitItem, даже если исходный объект является PackageKitItem.
Я думаю, что вы должны сделать в этих обстоятельствах добавить в KitItem:
public virtual KitItem ShallowCopy()
{
return (KitItem) this.MemberwiseClone();
}
и в PackageKitItem:
public override KitItem ShallowCopy()
{
return (PackageKitItem) this.MemberwiseClone();
}
Таким образом, вы получите правильный вызов MemberwiseClone () в зависимости от объекта, который вы пытаетесь использовать ShallowCopy (). Р>
Если вы хотите пойти дальше, вы можете определить ShallowCopy () в Product (возвращая Product), а затем иметь переопределенные версии в KitItem и PackageKitItem, каждый из которых возвращает свою соответствующую мелкую копию.
Другие советы
Как ни странно, я не получил ошибку при этом в 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;
}
В своем конструкторе Product вы уже делаете какую-то мелкую копию, не так ли? Если вы не перезаписали свой конструктор, тогда вы сможете просто создать новый PackageKitItem, который получает KitItem в качестве своего параметра.
PackageKitItem tempPackKitItem = new tempPackKitItem(kitItem);
Может быть, я просто неправильно понял ваш вопрос.