这是工人阶级:
namespace Lite
{
public class Spec
{
public int ID { get; set; }
public string Name { get; set; }
public string FriendlyName { get; set; }
public int CategoryID { get; set; }
public int Width { get; set; }
public int Height { get; set; }
public string UOM { get; set; }
public int Pagination { get; set; }
public int ColoursFront { get; set; }
public int ColoursBack { get; set; }
public string Material { get; set; }
public int GSM { get; set; }
public string GSMUOM { get; set; }
public bool Seal { get; set; }
public Spec(int ID)
{
using (CrystalCommon.MainContext db = new CrystalCommon.MainContext())
{
var q = (from c in db.tblSpecifications where c.id == ID select c).SingleOrDefault();
if (q != null)
loadByRec(q);
}
}
public Spec(CrystalCommon.tblSpecification Rec)
{
loadByRec(Rec);
}
public void loadByRec(CrystalCommon.tblSpecification Rec)
{
this.ID = Rec.id;
this.Name = Rec.Title;
this.Width = Convert.ToInt32(Rec.FinishedSizeW.Value);
this.Height = Convert.ToInt32(Rec.FinishedSizeL.Value);
this.UOM = Rec.FlatSizeUOM;
this.Pagination = Rec.TxtPagination.Value;
this.ColoursFront = Convert.ToInt32(Rec.TxtColsF.Value);
this.ColoursBack = Convert.ToInt32(Rec.TxtColsB.Value);
this.Material = Rec.TxtMaterial;
this.GSM = Rec.TxtGSM.Value;
this.GSMUOM = Rec.txtGsmUnit;
this.Seal = Rec.TxtSeal.Value == 1;
}
public string displayDimensions()
{
return Width + " x " + Height + " " + UOM;
}
}
}
然后我尝试修改Name
getter和setter:
namespace Lite
{
public class Spec
{
public int ID { get; set; }
// User friendly name if available otherwise fall back on spec name
public string Name { get {
if (null != FriendlyName)
return FriendlyName;
else
return Name;
}
set
{
Name = value;
}
}
public string FriendlyName { get; set; }
public int CategoryID { get; set; }
public int Width { get; set; }
public int Height { get; set; }
public string UOM { get; set; }
public int Pagination { get; set; }
public int ColoursFront { get; set; }
public int ColoursBack { get; set; }
public string Material { get; set; }
public int GSM { get; set; }
public string GSMUOM { get; set; }
public bool Seal { get; set; }
public Spec(int ID)
{
using (CrystalCommon.MainContext db = new CrystalCommon.MainContext())
{
var q = (from c in db.tblSpecifications where c.id == ID select c).SingleOrDefault();
if (q != null)
loadByRec(q);
}
}
public Spec(CrystalCommon.tblSpecification Rec)
{
loadByRec(Rec);
}
public void loadByRec(CrystalCommon.tblSpecification Rec)
{
this.ID = Rec.id;
this.Name = Rec.Title;
this.Width = Convert.ToInt32(Rec.FinishedSizeW.Value);
this.Height = Convert.ToInt32(Rec.FinishedSizeL.Value);
this.UOM = Rec.FlatSizeUOM;
this.Pagination = Rec.TxtPagination.Value;
this.ColoursFront = Convert.ToInt32(Rec.TxtColsF.Value);
this.ColoursBack = Convert.ToInt32(Rec.TxtColsB.Value);
this.Material = Rec.TxtMaterial;
this.GSM = Rec.TxtGSM.Value;
this.GSMUOM = Rec.txtGsmUnit;
this.Seal = Rec.TxtSeal.Value == 1;
}
public string displayDimensions()
{
return Width + " x " + Height + " " + UOM;
}
}
}
在我的计算机上编译很好,但服务器运行时似乎崩溃了。 (第一个版本工作正常)。我的同事在他的机器上对它进行了编译,并且它显然出现了“堆栈溢出错误”,但他现在还没有找到具体内容。
我在这里正确使用了吸气剂吗?
答案 0 :(得分:11)
这是一个无限循环:
public string Name { get {
...
set
{
Name = value;
}
}
setter会反复调用自己,直到出现Stack溢出异常。
通常你有一个支持变量,所以它最终会像这样
private string name;
public string Name {
get {
if (null != FriendlyName)
return FriendlyName;
else
return name;
}
set {
name = value;
}
}
答案 1 :(得分:5)
你的集合引用了属性本身,你的get引用了属性本身,这两个都会导致一个潜在的无限循环,导致StackOverflowException
(没有更多的堆栈空间来推送当前的调用)。您需要使用支持字段:
private string _name;
public string Name
{
get
{
if (null != FriendlyName)
return FriendlyName;
else
return _name;
}
set
{
_name = value;
}
}
看起来您试图将自动属性变为手动属性。自动属性(public string Name { get; set; }
)起作用,因为编译器将自己创建支持字段。
作为一项学习练习,如果您逐步使用调试器并将步骤 return Name
或Name = value
,您将看到第一手代码返回到属性中已经在。
答案 2 :(得分:2)
这要好得多。
string _name = "";
public string Name
{
get { return FriendlyName ?? _name; }
set { _name = value; }
}
答案 3 :(得分:1)
您的一个属性获取并设置自己,请参阅:
public string Name
{
get {
if (null != FriendlyName)
return FriendlyName;
else
return Name; //<-- StackOverflow
}
set
{
Name = value; //<-- StackOverflow
}
}
答案 4 :(得分:1)
你有一个名字的getter,它调用属性Name,它将调用Name的getter等。你需要一个私有字段来支持该属性,你需要访问getter中的那个支持字段。 / p>
答案 5 :(得分:0)
public string Name { get {
if (null != FriendlyName)
return FriendlyName;
else
return Name;
}
set
{
Name = value;
}
}
Name
/ get
中的 set
指的是该属性。您需要定义一个支持字段并使用它。
答案 6 :(得分:0)
如果FriendlyName
为null
,则Name
获取者会尝试从Name
获取者获取值 - 即它会循环播放。这是导致堆栈溢出的原因。
答案 7 :(得分:0)
不,您应该使用支持字段。错误发生在else
public string Name { get {
if (null != FriendlyName)
return FriendlyName;
else
return Name;//error, you're calling the property getter again.
}