2009-11-04 137 views
2

我有我使用的學習C#結構這個非常簡單的例子:調用非默認的結構構造函數內的構造方法

struct ScreenPosition 
{ 
    // These are the two private members of the structure 
    private int x; 
    private int y; 

    private int RangeCheckedX(int xPos) 
    { 
     if (xPos < 0 || xPos > 1280) 
     { 
      throw new ArgumentOutOfRangeException("X"); 
     } 
     return xPos; 
    } 

    private int RangeCheckedY(int yPos) 
    { 
     if (yPos < 0 || yPos > 1024) 
     { 
      throw new ArgumentOutOfRangeException("Y"); 
     } 
     return yPos; 
    } 

    // Declaring the non-default constructor 
    public ScreenPosition(int X, int Y) 
    { 
     this.x = RangeCheckedX(X); // ERROR HERE 
     this.y = RangeCheckedY(Y); // ERROR HERE 
    } 

    // Declaring the property X - Follows a syntax. See the C# quick reference sheet 
    public int X 
    { 
     get 
     { 
      return this.x; 
     } 

     set 
     { 
      this.x = RangeCheckedX(value); 
     } 
    } 
    // Declaring the property X - Follows a syntax. See the C# quick reference sheet 
    public int Y 
    { 
     get 
     { 
      return this.y; 
     } 

     set 
     { 
      this.y = RangeCheckedY(value); 
     } 
    } 
} 

我得到這個錯誤在「ERROR HERE」註釋行:

的之前所有字段被分配到

不能使用「這個」對象是不是非法調用結構的方法在非默認構造函數爲結構成員賦值?

+1

請檢查以下內容:http://www.jaggersoft.com/pubs/StructsVsClasses.htm 我在兩分鐘內就瞭解了更多關於結構的信息,這比我想象的更多。 – 2009-11-04 05:55:24

+3

您正在創建一個可變結構。我會重新考慮這個設計。 – sisve 2009-11-04 06:42:18

回答

5

您可以使這些方法成爲靜態並且可以工作,但是在分配所有字段之前,您無法調用非靜態方法。

2

在所有字段(屬性)填充之前,不允許在結構上調用方法。

我知道它的黑客,但這將工作。

struct ScreenPosition 
{ 
    // These are the two private members of the structure 
    private int x; 
    private int y; 

    private int RangeCheckedX(int xPos) 
    { 
     if (xPos < 0 || xPos > 1280) 
     { 
      throw new ArgumentOutOfRangeException("X"); 
     } 
     return xPos; 
    } 

    private int RangeCheckedY(int yPos) 
    { 
     if (yPos < 0 || yPos > 1024) 
     { 
      throw new ArgumentOutOfRangeException("Y"); 
     } 
     return yPos; 
    } 

    // Declaring the non-default constructor 
    public ScreenPosition(int X, int Y) 
    { 
     this.x = X; 
     this.y = Y; 
     this.x = RangeCheckedX(X); 
     this.y = RangeCheckedY(Y); 
    } 

    // Declaring the property X - Follows a syntax. See the C# quick reference sheet 
    public int X 
    { 
     get 
     { 
      return this.x; 
     } 

     set 
     { 
      this.x = RangeCheckedX(value); 
     } 
    } 
    // Declaring the property X - Follows a syntax. See the C# quick reference sheet 
    public int Y 
    { 
     get 
     { 
      return this.y; 
     } 

     set 
     { 
      this.y = RangeCheckedY(value); 
     } 
    } 
} 
+0

它會工作,但使方法靜態是一個不那麼hacky方法國際海事組織。 – 2009-11-04 06:23:19

2

GBegen有正確的想法 - 使範圍檢查方法靜態。

這不僅會解決問題,還會使代碼更加清晰:方法不依賴於結構的狀態,而且它們不是多態的,所以它們不應該「 t是實例方法。

+0

非常感謝。你的解釋最「可消化」。 – KalC 2009-11-04 19:31:34

1

在驗證輸入之前,您可以將每個字段設置爲零。這是有道理的,因爲無論如何,默認構造函數會將它們設置爲零,所以這是一個必須在程序中處理的情況。一旦設置了值,即使在構造函數中,也可以調用所需的任何方法。

但正確的解決方案是其他人都在說的:使範圍檢查靜態方法。事實上,在這種情況下,它們是純函數(沒有副作用,僅對參數而不是靜態或實例字段進行操作)。純函數總是可以是靜態的。而且,從調試,多線程,性能等角度來看,靜態純函數是巧克力覆蓋的。真棒