2011-08-17 16 views
1

這是工人階級:#1錯誤C#與getter和setter

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

在我的電腦這個編譯罰款,但服務器運行時似乎崩潰。 (第一個版本正常工作)。我的同事在他的機器上編譯了它,顯然它拋出了「堆棧溢出錯誤」,但他現在不在我身邊了。

我在這裏正確應用吸氣劑?

回答

11

這是一個死循環:

public string Name { get { 
    ... 
    set 
    { 
    Name = value; 
    } 
} 

的setter方法反覆調用自身,直到你得到的堆棧溢出異常。

通常你有一個後盾變量,所以它最終這樣

private string name; 
public string Name { 
    get { 
    if (null != FriendlyName) 
     return FriendlyName; 
    else 
     return name; 
    } 
    set { 
    name = value; 
    } 
} 
1

你的一個屬性獲取並設置本身,請參閱:

public string Name 
    { 
     get { 
     if (null != FriendlyName) 
      return FriendlyName; 
     else 
      return Name; //<-- StackOverflow 
     } 
     set 
     { 
      Name = value; //<-- StackOverflow 
     } 
    } 
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 NameName = value你會看到第一手準備回屬性的代碼你已經英寸

0
public string Name { get { 
      if (null != FriendlyName) 
       return FriendlyName; 
      else 
       return Name; 
      } 
      set 
      { 
       Name = value; 
      } 
     } 

Nameget/set指的是財產。您將需要定義一個支持字段並使用它。

0

如果FriendlyNamenull那麼Name吸氣試圖從Name吸氣獲得的價值 - 即它循環。這是導致堆棧溢出的原因。

0

不,您應該使用支持字段。該錯誤是在else

 public string Name { get { 
     if (null != FriendlyName) 
      return FriendlyName; 
     else 
      return Name;//error, you're calling the property getter again. 
     } 
1

您有名稱一個getter,調用屬性名稱,它會調用名稱,吸氣,等你需要一個私有字段來支持財產,你需要取而代之的是訪問你的getter中的後臺字段。

2

這樣好多了。

string _name = ""; 
public string Name 
{ 
    get { return FriendlyName ?? _name; } 
    set { _name = value; } 
}