2008-12-17 56 views
2

我有一個簡單的代碼:隨機串生成 - 兩個生成一個又一個給相同的結果

public string GenerateRandomString() 
     { 
      string randomString = string.Empty; 
      Random r = new Random(); 
      for (int i = 0; i < length; i++) 
       randomString += chars[r.Next(chars.Length)]; 

      return randomString; 
     } 

如果我調用這個函數來生成兩個字符串,一個接一個,它們是相同的...但如果我通過兩行生成字符串進行調試 - 結果是不同的。 有誰知道爲什麼會發生?

+0

你的代碼甚至沒有編譯 - 其餘部分在哪裏? – 2008-12-17 22:56:50

回答

5

發生這種情況是因爲調用彼此非常接近(在相同的毫秒內),那麼隨機構造函數將爲Random對象設置相同的值(默認情況下,它使用日期&時間)。

所以,實際上有兩種解決方案。

1.提供您自己的種子值,這在每次構建Random對象時都是唯一的。

2.始終使用相同的隨機對象 - 只構造一次。

就我個人而言,我會用第二種方法。它可以通過使Random對象成爲靜態,或使其成爲類的成員來完成。

+0

yup,Random根據當前時間選擇一個初始種子,所以一個小時間delta會給出相同的種子。 – Jimmy 2008-12-17 22:54:36

1

隨機(您正在使用的)的默認構造函數使用基於當前時間的值爲生成器播種。如果以毫秒爲單位的時間在函數的第一次和第二次調用之間沒有變化,它將使用相同的隨機種子。

我的建議是使用一個靜態隨機對象,並只初始化一次。

2

這是因爲你在同一時間創建兩個隨機對象。這是給它相同的種子,所以你會得到相同的數字。

當你調試它時,創建允許它們獲得不同種子的隨機對象之間有時間。

5

上述答案是正確的。我會建議您的代碼,但以下更改:

1)我會建議使用StringBuilder,而不是追加到字符串所有的時間。字符串是不可變的,所以每次添加字符串時都會創建一個新字符串。如果您從未使用過StringBuilder,請查看它。這對於這類工作非常有用。

2)如果將長度傳遞給方法本身,可以使您的方法更容易重用。你可能也可以傳遞字符數組,但是我已經把它排除了。

3)每次使用相同的隨機對象,如上所述。

public string GenerateRandomString(int length) 
{ 
    StringBuilder randomString = new StringBuilder(length); 

    for (int i = 0; i < length; i++) 
     randomString.Append(chars[(int)(_RandomObj.Next(chars.Length))].ToString()); 

    return randomString.ToString(); 
} 
1

由於Random生成器與系統時鐘綁定,因此您可能會在該時間段內顯示相同的結果。有幾種方法可以糾正。如果您正在使用循環,則將Random rnd = new Random();放置在循環之外。

Random rnd = new Random();行放在聲明變量的位置,並在整個程序中使用相同的變量(本例中爲rnd)。

這將在大多數情況下工作。