James Michael Hare

...hare-brained ideas from the realm of software development...
posts - 137 , comments - 1099 , trackbacks - 0

My Links

News

Welcome to my blog! I'm a Sr. Software Development Engineer in Seattle, WA. I've been doing C++/C#/Java development for over 18 years, but have definitely learned that there is always more to learn!

All thoughts and opinions expressed in my blog and my comments are my own and do not represent the thoughts of my employer.

Blogs I Read

MCC Logo MVP Logo

Follow BlkRabbitCoder on Twitter

Tag Cloud

Archives

Post Categories

C#/.NET Little Wonders: The Enumerable.Range() Static Method

Once again, in this series of posts I look at the parts of the .NET Framework that may seem trivial, but can help improve your code by making it easier to write and maintain. The index of all my past little wonders posts can be found here.

Thanks for all of your patience while I’ve been dealing with other matters these last few weeks.  I didn’t want to let my post slide a third week, so I decided to say a few words about a small static method in the Enumerable class from System.Linq

Using Range() to generates a sequence of consecutive integers

So, if we look in the Enumerable static class, where most of the linq extension methods are defined, we will also see a static method called Range() whose purpose is to generate a range of integers from a given start value and for a given count. 

It’s syntax looks like:

  • Range(int start, int count)
    • Returns a sequence of int from start to (start + count – 1).

So, for example, the code snippet below will create an List<int> of the numbers from 1 to 10:

   1: var numbers = Enumerable.Range(1, 10).ToList();

So, this seems simple enough, right? Well, yes, it is a handy way to create a sequence of consecutive int values that you can use directly, but when coupled with other constructs, it has many other uses as well.

Using Range() to feed a more complex LINQ expression

For example, if we wanted a list of the first 5 even numbers, we could start with the number of expected items and multiply up by our step factor in a Select():

   1: // take sequence 0, 1, 2, 3, 4 and multiply each by two...
   2: var evens = Enumerable.Range(0, 5).Select(n => n*2).ToList();

Or, you could create a range over the total range of values and use Where() to filter it down:

   1: // generates sequence from 0..9, but only selects even ones
   2: var odds = Enumerable.Range(0, 10).Where(n => (n % 2) == 0).ToList();

But the great thing about Range() is you don’t have to use it to just produce numbers, you can use the sequence it generates either directly or as the starting point for a more complex LINQ expression. 

For example, if we wanted to generate a series of strings for font sizes we want to allow in a windows form, we could do that easily:

   1: // takes the range from 1 to 10 and multiples by 10 and puts % on end.
   2: var percentages = Enumerable
   3:     .Range(1, 10)
   4:     .Select(i => (i * 10) + " pt")
   5:     .ToArray();

This would give us an array of strings containing “10 pt”, “20 pt”, “30 pt”, … “100 pt”.

So Range() comes in handy for any expression you can create that starts with a simple sequence of integers.  But what else?

Using Range() to generate multiple complex objects

One other use of Range() that can come in handy is for repeating some action multiple times.  For example, say we want to create and start several Task instances for some parallel work.

We could do this using a standard array allocation and for loop:

   1: // first construct the array of the appropriate size
   2: Task[] tasks = new Task[NumConsumers];
   3:  
   4: // then loop through each index and create the new instance
   5: for (int i = 0; i < NumConsumers; i++)
   6: {
   7:     tasks[i] = TaskFactory.StartNew(SomeAction);
   8: }

Or we could do it in one LINQ expression:

   1: // constructs an array of NumConsumers tasks that will each 
   2: // perform SomeAction in parallel
   3: Task[] tasks = Enumerable.Range(1, NumConsumers)
   4:     .Select(i => TaskFactory.StartNew(SomeAction))
   5:     .ToArray();

Now, you may be wondering why we can’t do this instead:

   1: // Enumerable.Repeat() repeats a value the specified number of times
   2: Task[] tasks = Enumerable.Repeat(TaskFactory.StartNew(SomeAction), NumConsumers)
   3:     .ToArray();

The answer is that Enumerable.Repeat() repeats the given value the specified number of times, so in the example above, it would call TaskFactory.StartNew() once and then repeat the resulting reference NumConsumers times, which is clearly not what we want!  There are ways to do similar things with Repeat(), but they’re not quite as straightforward as using Range().

Summary

The Enumerable.Range() method performs a very simple function, but it’s results can be used to drive much more complex LINQ expressions.  Feel free to use it for generating simple int sequences all the way to generating sequences of a repeated action.  Either way, it’s a good tool to keep handy.

 

Technorati Tags: , , , , , ,

Print | posted on Thursday, April 26, 2012 7:11 PM | Filed Under [ My Blog C# Software .NET Little Wonders ]

Feedback

Gravatar

# re: C#/.NET Little Wonders: The Enumerable.Range() Static Method

Though I did know the Enuermable.Range()-Method, this article was worth reading.
Keep up the good work and hopefully you continue this series of little wonders. :)
4/26/2012 11:40 PM | Shion
Gravatar

# re: C#/.NET Little Wonders: The Enumerable.Range() Static Method

Unexpected and interesting usage of Enumerable.Range
Thanks!
5/11/2012 6:38 AM | Wizou
Post A Comment
Title:
Name:
Email:
Comment:
Verification:
 

Powered by: