Pregunta

Estoy tratando de averiguar por qué me estoy haciendo una excepción de desbordamiento de pila. Estoy creando un simple juego de cartas para una tarea escolar y cuando clonar las tarjetas de devolverlos tengo la excepción de desbordamiento de pila.

Así que tengo esta clase de tarjeta:

public class Card : ICloneable
{
    ....

    #region ICloneable Members

    public object Clone()
    {
        return this.Clone(); // <--- here is the error thrown when the first card is to be cloned
    }

    #endregion
}

y tengo una clase llamada Hand que luego se clona las tarjetas:

internal class Hand
{
        internal List<Card> GetCards()
        {
            return m_Cards.CloneList<Card>(); // m_Cards is a List with card objects
        }
}

Por último, me consiguió un método de extensión para el List:

    public static List<T> CloneList<T>(this List<T> listToClone) where T : ICloneable
    {
        return listToClone.Select(item => (T)item.Clone()).ToList();
    }

El error se tira en la clase de tarjeta (método IClonable),

  

Una excepción no controlada del tipo 'System.StackOverflowException' producido en CardLibrary.dll

¿Fue útil?

Solución

Usted está llamando a ti mismo:

public object Clone()
{
    return this.Clone();
}

Esto se traduce en una recursión infinita.

Su método clone () debe copiar todas las propiedades / campos a un nuevo objeto:

public object Clone()
{
    Card newCard = new Card();

    newCard.X = this.X;
    // ...

    return newCard;
}

o puede utilizar MemberwiseClone ()

public object Clone()
{
    return MemberwiseClone();
}

Pero eso le da menos control sobre el proceso de clonación.

Otros consejos

he tendido a utilizar MemberwiseClone () para los datos simples, y luego implementado ICloneable throghout la jerarquía de los elementos que he necesitado para clonar, así:

public class CRMLazyLoadPrefs : ICloneable
{
    public bool Core { get; set; }
    public bool Events { get; set; }    
    public bool SubCategories { get; set; }
    public OrganisationLazyLoadPrefs { get; set; }

    public object Clone()
    {
        CRMLazyLoadPrefs _prefs = new CRMLazyLoadPrefs();
        // firstly, shallow copy the booleans
        _prefs  = (CRMLazyLoadPrefs)this.MemberwiseClone();
        // then deep copy the other bits
        _prefs.Organisation = (OrganisationLazyLoadPrefs)this.Organisation.Clone();
    }
}

Donde OrganisationLazyLoadPrefs también implementa ICloneable y así sucesivamente y así sucesivamente a lo largo de la jerarquía.

Espero que esta ayuda, Salud, Terry

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top