Pergunta

Estou tentando descobrir por que estou obtendo uma exceção de estouro de pilha. Estou criando um jogo de cartas simples para uma tarefa escolar e, quando clono as cartas para devolvê -las, recebo a exceção de transbordamento de pilha.

Então eu recebi esta aula de cartão:

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 eu tenho uma aula chamada Hand que então clém dos cartões:

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

Por último, recebi um método de extensão para o List:

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

O erro é lançado na classe de cartão (método iClonable),

Uma exceção não tratada do tipo 'System.StackOverflowException' ocorreu em cardlibrary.dll

Foi útil?

Solução

Você está se chamando:

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

Isso resulta em recursão infinita.

Seu método clone () deve copiar todas as propriedades/campos para um novo objeto:

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

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

    return newCard;
}

ou você pode usar o membroWISECLONE ()

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

Mas isso oferece menos controle sobre o processo de clonagem.

Outras dicas

Eu tendia a usar Memberwiseclone () para obter dados simples e, em seguida, implementei o ICLoneable Threghout a hierarquia de elementos que eu precisava clonar, então:

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

Onde a organização LAZYLOADPREFS também implementa iCloneable e assim por diante ao longo da hierarquia.

Espero que isso ajude, aplausos, Terry

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