簡體   English   中英

如何在C#中的類的構造函數中生成隨機數

[英]How to generate a random number in the constructor of a class in C#

我知道在C#中的類的構造函數中調用方法不是一個好習慣,但我堅持了一些奇怪的想法。 我的問題是,當我創建類的對象時,我需要為對象中的字段分配一個隨機數。

例如

class RandomNumberHandler
    {
        private int randomNumber;
        public RandomNumberHandler()
        {
            this.randomNumber = GenerateRandomNumber();
        }

        private int GenerateRandomNumber()
        {
            return (new Random()).Next(3000) + 1000;
        }
    }

就我而言,我需要一個四位數的數字。 我想在要創建對象的類中生成隨機數並將其作為參數傳遞給構造函數,但在其他類中生成隨機數似乎也不是一個好主意,因為我正試圖實現強大的凝聚力我的課。 我正在為我大學的“高質量代碼”課程而做,我正在尋找最好的方法。 任何想法如何做到這一點,歡迎:)

首先,在構造函數中調用非虛擬方法沒有任何問題 你在哪里讀的? (注意:調用虛擬方法可能是一個問題;這不是自動禁止,但您需要非常小心地觀察正在做的事情)。

順便說一句,每次調用GenerateRandomNumber都生成一個新的Random實例似乎很浪費。 您可以將Random實例提取到字段中以解決此問題:

class RandomNumberHandler
{
    private readonly Random random = new Random();
    private int randomNumber;

    public RandomNumberHandler()
    {
        this.randomNumber = GenerateRandomNumber();
    }

    private int GenerateRandomNumber()
    {
        return this.random.Next(3000) + 1000;
    }
}

但這又引發了一個問題:如果GenerateRandomNumber在每個實例的生命周期中(在構造函數中)僅被調用一次,那么為每個對象創建一個新的Random毫無意義。 因此,下一步的邏輯就是使random成為static 這意味着GenerateRandomNumber也可以變成static (實際上,它必須如此):

class RandomNumberHandler
{
    private static readonly Random Random = new Random();
    private int randomNumber;

    public RandomNumberHandler()
    {
        this.randomNumber = GenerateRandomNumber();
    }

    private static int GenerateRandomNumber()
    {
        return Random.Next(3000) + 1000;
    }
}

該代碼可以正常工作-除非您快速連續調用它,否則您可能會獲得“相同”的隨機數。

當然,您可以通過使用靜態隨機數(如果使用多個線程,請使用鎖以確保線程安全)來輕松解決此問題,例如:

class RandomNumberHandler
{
    private static Random random = new Random();
    private static object syncObj = new object();

    private int randomNumber;
    public RandomNumberHandler()
    {
        this.randomNumber = GenerateRandomNumber();
    }

    private static int GenerateRandomNumber()
    {
        lock(syncObj)
            return random.Next(3000) + 1000;
    }
}

隨機數生成器僅生成一個隨機數

簡短的答案:您應該在所有Next()調用中使用相同的Random實例。

我只是通過將Random類包裝在另一個名為RandomHandler的類中而看不到任何內聚。 我個人認為那很尷尬。 如果您需要一個全新的完全隨機數,則只需調用Random()。Next(3000)或您在構造函數中所說的任何內容即可。

如果將Random實例提升為靜態字段,並將GenerateRandomNumber設為靜態,則可以在randomNumber字段的聲明中調用它:

class RandomNumberHandler {
  private static Random random = new Random();
  private int randomNumber = GenerateRandomNumber();

  private static int GenerateRandomNumber() {
    return random.Next(3000) + 1000;
  }
}

或更簡單(且可讀性更差):

class RandomNumberHandler {
  private static Random random = new Random();
  private int randomNumber = random.Next(3000) + 1000;
}

盡管看起來不像在構造函數中調用方法,但是如果您查看生成的CIL,就會發現您是。

另外,如果您關心線程安全,請參閱本文

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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