我遇到了一个非常有趣的运行时错误,它会生成恶意堆栈溢出。
我已经定义了如下结构:
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来修复它,但我需要它既可读又可写,并返回默认值 - 任何想法?
答案 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)
您的属性永远不会获得您设置的值,因为它们始终返回相同的值(而不是存储的值)
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;}
}