Stack overflow exception thrown from overridden property from abstract base class

匿名 (未验证) 提交于 2019-12-03 02:41:02

问题:

I have a base class with the following (trimmed for brevity) declaration:

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   } } 

Which is used by the following class:

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)    {    } }  

Now when I bind my specific object to my model (my implementation happens to be MVC) the object is returned just fine if I only access the RecordID and the ObjectName, but I get a stack overflow exception if the get or set accessors to my (overridden) Status is hit.

I found a similar question on SO already...

Why does Property Set throw StackOverflow exception?

... but going by the auto-property implementation, my code looks like it would be correct and not create an infinite loop (but this does appear to be the case). Any ideas on how I would correctly override that property?

Thanks!

回答1:

The setter in MySpecificClass shouldn't be a problem, but the getter definitely is - internally, a call to an instance of MySpecificClass's Status will be making a call to itself to see which value to return which will make a call to itself to see... well. You get the idea.

I'd use a protected class variable rather than an auto-property.

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


回答2:

This is "By Design".

In the setter of Status you are calling this.Status = value. Status is a virtual property and hence it will bind right back to the setter of MySpecificClass.Status.

If you want to access the base property use base. instead

base.Status = value; 


回答3:

The abstract property declaration in the base class just states: "derived classes MUST implement a property called Status, with a getter and setter". In your derived class, calling this.Status inside your getter is illegal (causes the stack overflow).

To fix this, use a property with a backing field in your derived class:

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


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!