C# version here.
The following is an extension method for getting the contents of any IEnumerable(Of T) object, e.g. an array or List(Of T), in random order:
Code:
Imports System.Runtime.CompilerServices
Public Module Enumerable
<Extension()> _
Public Function Randomise(Of T)(ByVal items As IEnumerable(Of T)) As IEnumerable(Of T)
Dim result As T() = Nothing
If items IsNot Nothing Then
Dim rng As New Random
result = (From item In items Order By rng.NextDouble()).ToArray()
End If
Return result
End Function
End Module
Note that it obeys the rules for extension methods, i.e. it's a member of a module, is decorated with the Extension attribute and takes the target type as the first argument. You might use it something like this:
vb.net Code:
Dim numbers As Integer() = {1, 2, 3, 4, 5, 6, 7, 8, 9}
For Each number In numbers.Randomise()
MessageBox.Show(number.ToString())
Next
Try running that repeatedly and you'll get a different order each time.
Note that you could write a regular method that does the same thing in earlier versions.
EDIT: It's been brought to my attention that there is a significant issue with this code that, while unlikely to be encountered, could cause the operation to fail. Here's a reimplementation that isn't susceptible to this issue:
vb.net Code:
Imports System.Runtime.CompilerServices
Public Module Enumerable
<Extension>
Public Function Randomise(Of T)(ByVal items As IEnumerable(Of T)) As IEnumerable(Of T)
Dim result As T() = Nothing
If items IsNot Nothing Then
Dim rng As New Random
result = items.ToArray()
'Generate one random value per item.
Dim keys = Array.ConvertAll(result, Function(item) rng.NextDouble())
'Sort the items by their corresponding random keys, thus randomising them.
Array.Sort(keys, result)
End If
Return result
End Function
End Module