Pergunta

Ok, então eu tenho uma classe base abstrata chamada de Produto, uma classe KitItem que herda do produto e uma classe PackageKitItem que herda KitItem. ie.

Product
KitItem : Product
PackageKitItem : KitItem

Eu tenho meus KitItems carregado e eu preciso para carregar uma coleção de PackageKitItems que são, efetivamente, cópias rasas de KitItems.

Atualmente estamos fazendo o que sente ao me uma cópia superficial hacky no construtor do produto assim:

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));
        }

Eu tentei a criação de uma cópia em KitItem assim:

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

e chamando-o assim:

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

mas eu recebo um elenco inválido. Estou à procura de idéias para a melhor maneira de alcançar este objetivo.

Foi útil?

Solução

O problema que você tem é que desde ShallowCopy () é um membro da KitItem, MemberwiseClone () é apenas copiando os campos KitItem e retornando um KitItem mesmo se o objeto original é um PackageKitItem.

Eu acho que você tem que fazer nessa circunstância add para KitItem:

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

e em PackageKitItem:

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

Assim, você terá a chamada MemberwiseClone adequada () feito de acordo com o objeto que você está tentando ShallowCopy ().

Se você quiser ir mais longe, você pode definir uma cópiasuperficial () no produto (devolução de um produto) e, em seguida, têm versões substituído em KitItem e PackageKitItem cada voltando sua respectiva cópia superficial.

Outras dicas

Estranhamente eu não recebi um erro fazer isso no Visual Studio 2008. Estou postando o código para que você possa ver o que estou ausente ou o que eu estou supondo errado. Meu palpite é que o problema está em um dos membros da classe que você não postar.

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;

}

Em seu construtor produto que já está fazendo algum tipo de cópia superficial, não é? Se você não tiver substituído o seu construtor, então você deve ser capaz de simplesmente criar um novo PackageKitItem que recebe uma KitItem como seu parâmetro.

PackageKitItem tempPackKitItem = new tempPackKitItem(kitItem);

Talvez eu mal a sua pergunta.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top