C# 中的堆栈溢出错误 - 但如何修复它?

发布于 2024-09-29 22:12:06 字数 683 浏览 7 评论 0原文

我遇到了一个非常有趣的运行时错误,它会生成恶意堆栈溢出。

我定义了一个结构如下:

public enum EnumDataType { Raspberry, Orange, Pear, Apple };

public class DataRequest
{
    public long DataSize 
    { 
        get { return 0; } 
        set { DataSize = value; } 
    }

    public EnumDataType DataType  
    { 
        get { return EnumDataType.Apple; } 
        set { DataType = value; } 
    }
}

以下几行工作完美:

DataRequest request = new DataRequest();
request.DataSize = 60;

但是,当我在代码中跳过以下行时,它会生成堆栈溢出:

request.DataType = EnumDataType.Raspberry;

当然,我可以通过删除默认值或使用 auto get/ 来修复它设置,但我需要它既可读又可写,并返回默认值 - 有什么想法吗?

I've run into a really interesting runtime bug which generates a rogue stack overflow.

I've defined a structure as follows:

public enum EnumDataType { Raspberry, Orange, Pear, Apple };

public class DataRequest
{
    public long DataSize 
    { 
        get { return 0; } 
        set { DataSize = value; } 
    }

    public EnumDataType DataType  
    { 
        get { return EnumDataType.Apple; } 
        set { DataType = value; } 
    }
}

The following lines work perfectly:

DataRequest request = new DataRequest();
request.DataSize = 60;

However, when I step over the following line in code, it generates a stack overflow:

request.DataType = EnumDataType.Raspberry;

Of course, I can fix it by removing the defaults, or using auto get/set, but I need it to be both readable and writable, and return a default - any ideas?

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

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

发布评论

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

评论(5

第几種人 2024-10-06 22:12:06
public long DataSize { get { return 0; } set { DataSize = value; } } 

您不断地设置DataSize 的值。您需要创建一个局部变量并使用它。例如

private long dataSize;

public long DataSize
{
    get { return this.dataSize; }
    set { this.dataSize = value; }
}

编辑
我已经编写了 DataSize 但同样适用于 DataType

public long DataSize { get { return 0; } set { DataSize = value; } } 

You are constantly setting the value of DataSize. You need to create a local variable and use that instead. e.g.

private long dataSize;

public long DataSize
{
    get { return this.dataSize; }
    set { this.dataSize = value; }
}

EDIT
I've written DataSize but the same applies to DataType

雪化雨蝶 2024-10-06 22:12:06

正如其他人所说,发生堆栈溢出是因为您的属性设置器只是调用自身。如果您将其视为一种方法,可能会更容易理解:

// This obviously recurses until it blows up
public void SetDataType(long value)
{
    SetDataType(value);
}

据我了解,您正在尝试创建普通属性但具有默认值,对吧?

在这种情况下,您需要由 setter 设置的支持变量 - 并且 getter 也应该返回这些变量。 变量应该获得默认值:

private long dataSize = 0;
public long DataSize {
  get { return dataSize; }
  set { dataSize = value; }
}

private EnumDataType dataType = EnumDataType.Apple;
public EnumDataType DataType { 
  get { return dataType; }
  set { dataType = value; }
}

或者,使用自动属性,但在构造函数中设置默认值:

public long DataSize { get; set; }
public EnumDataType DataType { get; set; }

public DataRequest()
{
    DataSize = 0; // Not really required; default anyway
    DataType = EnumDataType.Apple;
}

As others have said, the stack overflow occurs because your property setter is just calling itself. It may be simpler to understand if you think of it as a method:

// This obviously recurses until it blows up
public void SetDataType(long value)
{
    SetDataType(value);
}

As I understand it, you're trying to create normal properties but with a default value, right?

In that case, you need backing variables which are set by the setters - and the getters should return those variables, too. It's the variables which should get default values:

private long dataSize = 0;
public long DataSize {
  get { return dataSize; }
  set { dataSize = value; }
}

private EnumDataType dataType = EnumDataType.Apple;
public EnumDataType DataType { 
  get { return dataType; }
  set { dataType = value; }
}

Alternatively, use automatic properties but set the defaults in your constructor:

public long DataSize { get; set; }
public EnumDataType DataType { get; set; }

public DataRequest()
{
    DataSize = 0; // Not really required; default anyway
    DataType = EnumDataType.Apple;
}
﹏半生如梦愿梦如真 2024-10-06 22:12:06

发生堆栈溢出是因为在设置器中您将属性设置为一个值(即您试图将某些东西设置为某个值...这会导致无限循环)...这意味着它尝试将自己设置为value 这意味着它尝试将自己设置为一个值,直到繁荣

您的属性将永远不会获得您正在设置的值,因为它们总是返回相同的值(而不是存储的值)

public enum EnumDataType { Raspberry, Orange, Pear, Apple }; 

public class DataRequest 
{ 
private long _dataSize = 0;
private EnumDataType _dataType = EnumDataType.Apple;

public long DataSize { get { return _dataSize ; } set { _dataSixe= value; } } 
public EnumDataType DataType  { get { return _dataType; } set { _dataType= value; } } 
} 

是您真正想要的

stack overflow happens because in the setter you are setting the property to a value (Ie you are trying to get something to set itself to something ... which causes an infinite loop) ... which means that it tries to set itself to a value which means its tries to set itself to a value untill boom

your properties will never get the values you are setting because they always return the same value (not the stored value)

public enum EnumDataType { Raspberry, Orange, Pear, Apple }; 

public class DataRequest 
{ 
private long _dataSize = 0;
private EnumDataType _dataType = EnumDataType.Apple;

public long DataSize { get { return _dataSize ; } set { _dataSixe= value; } } 
public EnumDataType DataType  { get { return _dataType; } set { _dataType= value; } } 
} 

is what you really wanted

是伱的 2024-10-06 22:12:06

你必须用后备存储来实现它:

private EnumDataType dataType;
public EnumDataType DataType  { get { return EnumDataType.Apple; } set { dataType = value; } }

}

你应该在任何时候在 getter 和 setter 中执行一些操作时这样做。顺便说一句,为什么你甚至可以设置变量?你无法读出它们,你总是得到 EnumDataType.Apple。如果你想要一个起始值,你可以这样做:

private EnumDataType dataType = EnumDataType.Apple;
public EnumDataType
{
   get
   {
       return dataType;
   }
   set
   {
       dataType = value;
   }
 }

you have to implemet it with a backing store:

private EnumDataType dataType;
public EnumDataType DataType  { get { return EnumDataType.Apple; } set { dataType = value; } }

}

You should do so anytime you do some acion in the getter and setters. By the way, why can you even set the variables? you can't read them out, you always get EnumDataType.Apple. If you want a start value, you can do like this:

private EnumDataType dataType = EnumDataType.Apple;
public EnumDataType
{
   get
   {
       return dataType;
   }
   set
   {
       dataType = value;
   }
 }
记忆で 2024-10-06 22:12:06

我不明白第一行如何:
请求数据大小 = 60;

不会导致堆栈溢出 - 我的建议是使用支持属性:

public class DataRequest
{
    protected int dataSize = 0;
    protected EnumDataType enumDataType;
    public long DataSize { get { return 0; } set { dataSize = value; } }
    public EnumDataType DataType  { get { return EnumDataType.Apple; } set { enumDataType = value;} 
}

I don't understand how the first line:
request.DataSize = 60;

Doesn't cause a stack overflow - my advice would be to use backing properties:

public class DataRequest
{
    protected int dataSize = 0;
    protected EnumDataType enumDataType;
    public long DataSize { get { return 0; } set { dataSize = value; } }
    public EnumDataType DataType  { get { return EnumDataType.Apple; } set { enumDataType = value;} 
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文