Question

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!

Was it helpful?

Solution

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

OTHER TIPS

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;

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

}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top