[英]Define maximum and minimum for fields in struct
我有一個struct
和一個整數變量。 我的變量值必須在1200和1599之間。但是在默認構造函數中,我無法控制變量的值。 如何在struct
執行此操作?
struct MyStruct
{
public int x;
public MyStruct(int x)
{
if(x>1599)
this.x=1599;
else if(x<1200)
this.x=1200;
else
this.x=x;
}
}
使用具有后備字段的屬性:
struct MyStruct
{
private const int MIN_VALUE = 1200;
private const int MAX_VALUE = 1599;
private int x;
public int X
{
get { return x + MIN_VALUE; }
set
{
if(value > MAX_VALUE)
x = MAX_VALUE;
else if(value < MIN_VALUE)
x = MIN_VALUE;
else
x = value;
x -= MIN_VALUE;
}
}
// constructor is not really needed anymore, but can still be added
}
我將屬性與我的setter和Damien_The_Unbeliever的getter結合使用,以使x
的初始狀態正確。 我也同意Tim關於“魔術數字”常量的觀點,並補充了這一點。 因此,請同時給予這兩個“我的答案”的榮譽。
就像DatVM已經說過的:根據通用C#命名准則,公共字段/屬性應以大寫字母開頭。 這也使您可以在后備字段中使用相同的名稱,但是以小寫字母開頭(我個人不喜歡丑陋的_)...
最后但並非最不重要的一點:請閱讀rexcfnghk的答案,即使它不是真正的答案也是如此,因為他也是絕對正確的。
關於使用屬性和私有后備字段的另一個變體:
struct MyStruct
{
private int x;
public MyStruct(int x)
{
if (x > 1599)
this.x = 399;
else if (x < 1200)
this.x = 0;
else
this.x = x - 1200;
}
public int X { get { return x+1200; } }
}
這樣可以確保默認構造的值在“范圍內”。
但是任何變體都會帶來一些開銷,因此這是否可以接受取決於您。
我的變量值必須在1200和1599之間
在C#中,您不能為struct
定義自己的默認構造struct
。 如果您有一個MyStruct
數組,例如var myArray = new MyStruct[5]
,則將調用MyStruct
的默認構造函數,並且myArray
中的所有元素的x
等於0,這根據您的要求是無效的。
這就是為什么我認為您的struct
設計不正確的原因。 根據框架設計指南
√DO確保所有實例數據被設置為零,假的,或者為空(如適當時)的狀態是有效的。
這樣可以防止在創建結構數組時意外創建無效實例。
如果在調用struct
的默認構造函數時需要參數驗證,請改用一個class
。
另外,您當前對MyStruct
設計使其可變。 請看看為什么可變結構是邪惡的 。
我將使用帶有getter和setter的屬性以及一個私有后備字段,在該字段中,您可以實現此邏輯,或者如果該值超出邊界,甚至拋出ArgumentOutOfRangeException
。
這是一個例子:
struct MyStruct
{
private const int MIN_VALUE = 1200;
private const int MAX_VALUE = 1599;
private int _X;
public int X
{
get { return _X; }
set { _X = checkBoundaries(value); }
}
private static int checkBoundaries(int x)
{
if (x > MAX_VALUE)
return MAX_VALUE;
else if (x < MIN_VALUE)
return MIN_VALUE;
else
return x;
}
public MyStruct(int x)
{
_X = checkBoundaries(x);
}
}
最好始終使用屬性,即使您一開始不需要限制訪問權限。 然后,如果需要,更容易實現這樣的邏輯。
最后一點:我建議使用類而不是struct。
_X
初始化為默認值0。 _X
,因為在結構中也不允許這樣做 您應該將x改為property
:
private int _x;
public int x {
get
{
return _x;
}
set
{
_x = value;
if (_x > 1599)
{
_x = 1599
}
else if (_x < 1200)
{
_x = 1200
}
}
}
PS:對於C#命名約定,應將其稱為X
(大寫)而不是x
如果一個結構(而不是使用公共字段)使用私有字段和公共屬性(該屬性將字段的默認值映射到該結構所需的默認值)來轉換該字段的值,則可以使該結構具有默認值。 例如,您可能有一個后備字段int _x_minus_1200;
並具有返回_x_minus_1200 + 1200
的屬性getter。 我不太熱衷於這種方法(通常,我更喜歡結構具有公共字段並表現得像結構,並且結構字段的含義和驗證是使用結構的代碼的函數),但在某些情況下,它們可以會有所幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.