抽象基类的重写属性抛出堆栈溢出异常

发布于 2024-08-02 07:28:20 字数 1241 浏览 3 评论 0原文

我有一个带有以下声明(为了简洁而进行了修剪)的基类:

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

由以下类使用:

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

现在,当我将特定对象绑定到我的模型时(我的实现恰好是 MVC),如果我只返回对象,则返回得很好访问 RecordID 和 ObjectName,但如果命中我的(覆盖的)状态的 get 或 set 访问器,我会收到堆栈溢出异常。

我已经发现了类似的问题...

为什么Property Set 是否会抛出 StackOverflow 异常?

...但是根据自动属性实现,我的代码看起来是正确的并且不会创建无限循环(但情况似乎确实如此)。关于如何正确覆盖该属性有什么想法吗?

谢谢!

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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

绝對不後悔。 2024-08-09 07:28:20

这就是“设计”。

在 Status 的设置器中,您调用 this.Status = value。 Status 是一个虚拟属性,因此它将直接绑定回 MySpecificClass.Status 的 setter。

如果您想访问基本属性,请使用 base.反而

base.Status = value;

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;
月光色 2024-08-09 07:28:20

基类中的抽象属性声明只是声明:“派生类必须实现一个名为 Status 的属性,并带有 getter 和 setter”。在派生类中,在 getter 内部调用 this.Status 是非法的(导致堆栈溢出)。

要解决此问题,请在派生类中使用带有支持字段的属性:

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

}

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

}
奢华的一滴泪 2024-08-09 07:28:20

MySpecificClass 中的 setter 应该不是问题,但 getter 肯定是问题 - 在内部,对 MySpecificClass Status 实例的调用将调用其自身以查看要返回哪个值,这将调用其自身来查看。 .. 出色地。你明白了。

我会使用受保护的类变量而不是自动属性。

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

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;
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文