Domanda

Sto cercando di scoprire perché io sono sempre un'eccezione di overflow dello stack. Sto creando un semplice gioco di carte per un compito scolastico e quando ho clonare le carte per tornare li ottengo l'eccezione di overflow dello stack.

Così ho preso questa classe carta:

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
}

e ho una classe chiamata Hand che poi clona le carte:

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

scorso, ho ottenuto un metodo di estensione per il List:

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

L'errore si butta nella classe carta (metodo IClonable),

  

Un'eccezione di tipo 'System.StackOverflowException' avvenuto in CardLibrary.dll

È stato utile?

Soluzione

Si sta chiamando te stesso:

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

Ciò si traduce in una ricorsione infinita.

Il tuo clone () metodo deve copiare tutte le proprietà / campi a un nuovo oggetto:

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

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

    return newCard;
}

o si potrebbe usare MemberwiseClone ()

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

Ma che ti dà meno controllo sul processo di clonazione.

Altri suggerimenti

Ho la tendenza a utilizzare MemberwiseClone () per i dati semplici, e quindi implementato ICloneable throghout la gerarchia degli elementi che ho avuto bisogno di clonare, così:

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

Dove OrganisationLazyLoadPrefs implementa anche ICloneable e così via e così via per tutta la gerarchia.

Spero che questo aiuti, Saluti, Terry

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top