2011-11-05 215 views
0

這是一個家庭作業,我們沒有學習C#中的結構(現在我正在學習)。所以我去msdn,但我沒有找到我的程序的問題... 是的,我不能翻譯完全分配給我的本地languange,我不明白編譯器的想法。C#結構編譯錯誤

UML我的功課:(我們必須使用它) 接口:IComparable的

  • +分母{獲得;}:長
  • +分母{獲得;}:長
  • +理性(分子:長,分母:長)
  • + GCD(一個:長,b:長):長
  • +等於(R:Rationaol):布爾
  • ...

而且我們不能實現其他方法或參數。

我用Java編寫了這個家庭作業,並且正確地工作。

我有一個很大的問題,我不明白是什麼意思以下誤差修改:

錯誤2支持字段的自動實現的屬性「Rational.Rational.Denominator」必須控制返回到之前被完全分配呼叫者。考慮從構造函數初始值設定項中調用默認構造函數。

錯誤3自動實現的屬性'Rational.Rational.Numerator'的備份字段必須在控制權返回給調用者之前完全分配。考慮從構造函數初始值設定項中調用默認構造函數。

錯誤4「這個」對象不能被所有字段之前使用分配給

我的代碼: 命名空間合理

{ 
    //  (Rational is underline)  here the 2 and 3 error 
    public struct Rational : IComparable<Rational> 
    { 
     public long Numerator { get; set; } 
     public long Denominator { get; set; } 

     public Rational(long num, long den) 
     { 
      // and here (GCD is underline) the 4. error 
      long simple = GCD(num, den); 
      this.Numerator = num/simple; 
      this.Denominator = den/simple; 
     } 

     public long GCD(long a, long b) 
     { 
      long c = Math.Abs(a); 
      long d = Math.Abs(b); 
      if (d == 0) return c; 
      return GCD(d, c % d); 
     } 

     public override string ToString() 
     { 
      if (Denominator==1) 
      { 
       return Numerator + ""; 
      } 
      return Numerator+"/"+Denominator; 
     } 

     public override bool Equals(object obj) 
     { 
      bool result = false; 
      if (obj is Rational) 
      { 
       Rational r = (Rational)obj; 
       result = this.Equals(r); 
      } 
      return result;    
     } 

     public bool Equals(Rational r) 
     { 
      if ((object)r ==null) 
      { 
       return false; 
      } 
      return this.Denominator == r.Denominator && this.Numerator == r.Numerator; 
     } 

     public int CompareTo(Rational other) 
     { 
     ... 

回答

1

您可以將this()添加到您的構造函數中,也可以通過由字段支持的屬性替換自動屬性。

public Rational(long num, long den) 
{ 
     // and here (GCD is underline) the 4. error 
     long simple = GCD(num, den); 
     this.Numerator = num; 
     this.Denominator = den; 
} 

在這裏,您分配一個值來支持你的屬性自動生成的字段,然後訪問實例方法GCD

您應該使此方法爲靜態。

接下來您將再次得到相同的錯誤,這次是因爲您訪問了自動屬性Numerator。您可以修復,通過保持汽車性能及增加:this()的構造器:

public Rational(long num, long den) 
    :this() 
{ 

這導致在字段中輸入您自己的構造函數的代碼運行之前被初始化爲0

另一種方法是切換到字段:從這個代碼中除了

public struct Rational : IComparable<Rational> 
{ 
    private long _numerator; 
    private long _denominator; 

    public long Numerator { get{return _numerator;}; set{_numerator=value;} } 
    public long Denominator{ get{return denominator;}; set{_denominator=value;} } 

    public Rational(long num, long den) 
    { 
     // and here (GCD is underline) the 4. error 
     long simple = GCD(num, den); 
     this._numerator = num; 
     this._denominator = den; 
    } 

有幾個問題:

1)您使用的是可變的結構。這通常是不好的設計。從你的房產中刪除二傳手,或將其設爲私人。

2)不重寫GetHashCode()要與Equals一致(或者它只是沒有在你的代碼片段所示)

3)我建議實施IEquatable<Rational>。您已經實施了Equals(Rational),因此您不需要添加任何其他方法。

4)你的代碼很容易產生int溢出。考慮使用BigInteger而不是long s。 5)除非你規範你的理性(分母大於0並且除以GCD),否則你會得到數學上相當於不相等的理性。

+0

是的,但這是我第一次在這裏大約可變結構:) 如果我從屬性中刪除setter,我得到了這個問題: 屬性或索引'Rational ....'不能被分配給 - 它是隻讀的 而通過UML,我必須刪除setter。但是,如果我將它設置爲私有(setter),那麼它將會很好:) – blaces

+0

只要搜索可變結構,就會發現很多問題。簡短的版本是,在某些情況下,可變結構具有奇怪的語義,人們寧願避免。公共setter的屬性不*,*不好,但任何變異的方法是。 – CodesInChaos

+0

如果你刪除了setter,你需要使用我的第三個代碼片段,我用場替換了自動屬性。然後你需要分配給字段,而不是構造函數中的屬性。 – CodesInChaos

0

我在你的構造通知書Rational您呼叫GCD並將結果存儲在simple中,但不使用結果。

+0

謝謝:)我在構造 – blaces

+0

修復這個問題:)這應該是一個評論 –

0

使您的GCD函數靜態。

它不使用任何實例成員,並且因爲它在實例成員設置之前被調用,所以它不能。

1

你需要調用默認的構造函數這個工作:

public Rational(long num, long den) : this() 
{ 
    // and here (GCD is underline) the 4. error 
    long simple = GCD(num, den); 
    this.Numerator = num; 
    this.Denominator = den; 
} 

這裏的一個更大的問題是,你有一個可變的結構。這絕不是一個好主意。我想使它:

public long Numerator {get; private set;} 
+0

謝謝你,我把作業的UML附在我的問題上。所以我必須以這種方式寫...但謝謝你的提示:) – blaces