簡體   English   中英

為結構中的字段定義最大值和最小值

[英]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改為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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM