C# Stack Overflow
-
20-09-2019 - |
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
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