C#中的堆栈溢出错误 - 但如何解决?

时间:2010-10-27 13:33:10

标签: c# stack-overflow

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

我已经定义了如下结构:

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 / set来修复它,但我需要它既可读又可写,并返回默认值 - 任何想法?

5 个答案:

答案 0 :(得分:19)

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

您不断设置DataSize的值。您需要创建一个局部变量并使用它。 e.g。

private long dataSize;

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

修改 我写过DataSize,但同样适用于DataType

答案 1 :(得分:12)

正如其他人所说的那样,堆栈溢出的发生是因为你的属性setter只是在调用它自己。如果您将其视为一种方法,可能会更容易理解:

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

答案 2 :(得分:4)

发生堆栈溢出是因为在setter中你将属性设置为一个值(即你试图将某些东西设置为某种东西......导致无限循环)...这意味着它试图设置本身就是一个价值,这意味着它试图将自己设定为一个直至繁荣的价值

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

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

是你真正想要的

答案 3 :(得分:3)

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

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

}

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

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

答案 4 :(得分:2)

我不明白第一行怎么样: request.DataSize = 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;} 
}