views:

4794

answers:

6

I was reading an article on MSDN Magazine about using the Enumerable class in LINQ to generate a random array. The article uses VB.NET and I'm not immediately sure what the equivalent is in C#:

Dim rnd As New System.Random()
Dim numbers = Enumerable.Range(1, 100). _
    OrderBy(Function() rnd.Next)
+4  A: 
Random rnd = new Random();
IEnumerable<int> numbers = Enumerable.Range(1, 100).OrderBy(r => rnd.Next);
James Curran
Hmmm, I'm getting: Hmmm, I'm getting: The type arguments for method 'System.Linq.Enumerable.OrderBy<TSource,TKey>(System.Collections.Generic.IEnumerable<TSource>, System.Func<TSource,TKey>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
Ryan
@Ryan: missing parens
Jimmy
+8  A: 

The Developer Fusion VB.Net to C# converter says that the equivalent C# code is:

System.Random rnd = new System.Random();
IEnumerable<int> numbers = Enumerable.Range(1, 100).OrderBy(r => rnd.Next());

For future reference, they also have a C# to VB.Net converter. There are several other tools available for this as well.

HanClinto
edited to be the combination of everyone's. this was top answer at the time. I'm not playing favorites, just keeping it clean.
TheSoftwareJedi
Okay, thanks for letting me know. Just for reference, this is James Curran's code.
HanClinto
+1  A: 

Best I can do off the top of my head without access to Visual Studio (crosses fingers):

System.Random rnd = New System.Random();
IEnumerable<int> numbers = Enumerable.Range(1, 100).OrderBy(rnd => rnd.Next);
Adam Alexander
+5  A: 

I initially thought this would be a bad idea since the sort algorithm will need to do multiple comparisons for the numbers, and it will get a different sorting key for the same number each time it calls the lambda for that number. However, it looks like it only calls it once for each element in the list, and stores that value for later use. This code demonstrates this:

int timesCalled = 0;
Random rnd = new Random();

List<int> numbers = Enumerable.Range(1, 100).OrderBy(r =>
   {
       timesCalled++;
       return rnd.Next();
   }
).ToList();

Assert.AreEqual(timesCalled, 100);
Daniel Plaisted
+1  A: 

Using the C5 Generic Collection Library, you could just use the builtin Shuffle() method:

IList<int> numbers = new ArrayList<int>(Enumerable.Range(1,100));
numbers.Shuffle();
Marcus Griep
I like it. Nice.
Ryan
+1  A: 

What about something far more easy...

Enumerable.Range(1, 100).OrderBy(c=> Guid.NewGuid().ToString())
FouZ