eccezione overflow dello stack lanciata da proprietà modificate da classe base astratta
-
19-09-2019 - |
Domanda
Ho una classe di base con la seguente (tagliati per brevità) dichiarazione:
public abstract class MyBaseClass
{
public int RecordId { get; private set; }
public string ObjectName { get; set; }
public abstract string Status { get; set; }
public GetMyObject(int id)
{
MyObject myObject = context.GetObjectById(id);
this.RecordId = myObject.RecordId;
this.ObjectName = myObject.ObjectName;
this.Status = myObject.Status
}
}
Che viene utilizzato dalla classe seguente:
public class MySpecificClass : MyBaseClass
{
public override string Status
{
get
{
if(this.Status == "something")
return "some status";
else
return "some other status";
}
set
{
this.Status = value;
}
}
public GetMySpecificObject(int id) : base(id)
{
}
}
Ora, quando mi legano mio oggetto specifico per il mio modello (la mia implementazione sembra essere MVC) l'oggetto viene restituito bene se accedo solo il RecordID e ObjectName, ma ottengo un'eccezione di overflow dello stack se le funzioni di accesso get o set al mio (override) Stato viene colpito.
Ho trovato una domanda simile su SO già ...
Perché Property Set buttare eccezione StackOverflow?
... ma andando dalla realizzazione di auto-proprietà, il mio codice è simile sarebbe corretto e non creare un loop infinito (ma questo non sembra essere il caso). Tutte le idee su come avrei ignorare correttamente che la proprietà?
Grazie!
Soluzione
Il setter in MySpecificClass non dovrebbe essere un problema, ma il getter è sicuramente - internamente, una chiamata a un'istanza di Stato di MySpecificClass sarà fare una chiamata a sé per vedere quale valore da restituire che effettuare una chiamata a se stesso per vedere ... bene. Si ottiene l'idea.
mi piacerebbe utilizzare una variabile di classe protetta, piuttosto che un auto-proprietà.
public abstract class MyBaseClass
{
protected string _status;
public virtual string Status
{
get { return _status; }
set { _status = value; }
}
}
public class MySpecificClass : MyBaseClass
{
public override string Status
{
get
{
if(_status == "something")
return "some status";
else
return "some other status";
}
set
{
_status = value;
}
}
}
Altri suggerimenti
Questa è "By Design".
Nel setter di Stato che si sta chiamando this.Status = valore. Stato è una proprietà virtuale e, quindi, si legherà, dritta verso il setter di MySpecificClass.Status.
Se si desidera accedere alla base alcune stanze sono di base. invece
base.Status = value;
La dichiarazione di proprietà astratta nella classe base afferma semplicemente: "classi derivate DEVE attuare una proprietà chiamata di stato, con un getter e setter". Nella classe derivata, chiamare this.Status all'interno del vostro getter è illegale (provoca l'overflow dello stack).
Per risolvere questo problema, utilizzare una proprietà con un campo supporto nella classe derivata:
public abstract class MyBaseClass
{
public abstract string Status { get; set; }
}
public class MySpecificClass : MyBaseClass
{
private string _status;
public override string Status
{
get
{
if(this._status == "something")
return "some status";
else
return "some other status";
}
set
{
_status = value;
}
}
}