C # desbordamiento de pila
-
20-09-2019 - |
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
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