[C#]如何得到真正亂的亂數

當我在開發我的第一個小專案 - 英文單字本 的時候,這個桌面應用程式,包含了單字測驗複習的功能。
於是我使用Random嘗試得到打亂順序的圖片路徑,再透過PictureBox將圖片顯示在畫面上,但是我發現,打亂的效果並沒有顯現出來,而且每次顯示圖片的順序都一模一樣,這時候我請求了大神的幫助!

 

我簡單的消化了大神說的概念:只要你的Random在一開始取得一樣的亂數種子(seed),或稱為亂數初始值,那麼你就會一直得到一樣的亂數序列,我想這就是為什麼,圖片顯示的順序一直都一樣的原因。
 

原始程式碼:

 private List<string> GetRandomImages()
{ 

//先用一個泛型集合來儲存所有圖片的路徑
         
List<string> files = Directory.GetFiles($@"C:\Users\ching\source\repos\A20200615\Vocabulary", "*.jpg",
                                        SearchOption.AllDirectories).ToList();

//使用Random隨機讀取圖片路徑(透過隨機的index)
Random rand = new Random();
using (var fs = new FileStream(files[rand.Next(files.Count)],
                               FileMode.Open, FileAccess.Read))
{
  myPictureBox.Image= Image.FromStream(fs);
}

return files;
}

這段程式碼運行結果就像之前說的,每次圖片顯示的順序都一樣!

解決方法:

 private List<string> GetRandomImages()
{
//先用一個泛型集合來儲存所有圖片的路徑
//再使用Linq的Orderby方法(指的是我們要以Random隨機得到GUID的HashCode來當亂數種子),
//以這個亂數排序法,來一一排序files集合裡的元素,x就是迭代器

files = Directory.GetFiles($@"C:\Users\ching\source\repos\A20200615\Vocabulary", "*.jpg",
                           SearchOption.AllDirectories).OrderBy(x => new Random(Guid.NewGuid().GetHashCode()).Next()).ToList();
            
//既然集合裡的元素,已經做了亂數排序,因此每次讀取集合裡的第一個元素都不是同一個
using (var fs = new FileStream(files.First(),
       FileMode.Open, FileAccess.Read))
{
myPictureBox.Image= Image.FromStream(fs);
}

return files;
}

這樣就解決了每次都顯示一樣順序圖片的困擾,測驗當然要保有未知的因素,才有測驗的意義嘛~(笑)。

參考資料:
https://prototypingideas.blogspot.com/2009/05/blog-post_06.html
https://dotblogs.com.tw/suehilary/2012/12/03/85341

如有敘述錯誤,還請不吝嗇留言指教,thanks!