tags:

views:

358

answers:

6

In F#, you can generate a set of numbers, just by saying [1..100].

I want to do something similar in C#. This is what I have come up with so far:

public static int[] To(this int start, int end)
{
    var result = new List<int>();
    for(int i = start; i <= end; i++)
        result.Add(i);
    return result.ToArray();
}

By doing this, I can now create a set by saying 1.To(100)

Unfortunately, this is not nearly as readable as [1..100]. Has anyone come up with a better way to do this in C#? Is it more readable if it is lowercase? 1.to(100), for instance? Or, is "To" a bad word? Is something like 1.Through(100) more readable?

Just looking for some thoughts. Has anyone else come up with a more elegant solution?

EDIT: After reading the responses, I have re-written my To method using the range:

public static int[] To(this int start, int end)
{
    return Enumerable.Range(start, end - start + 1).ToArray();
}

I am still looking for thoughts on the readability of 1.To(100)

+8  A: 

Enumerable.Range(1, 100);

TT
That method is useful. Thanks. It is less readable than 1.To(100), but I can use it in the implementation, of To() at least.
Brian Genisio
I should expand on why I think it is less readable... it is because I actually need an array, which becomes: Enumerable.Range(1, 100).ToArray()
Brian Genisio
I would say that 1.To(100) can be misunderstood. To me it sounds like a cast. Also Enumerable.Range has the advantage of being implemented in the .net framework and therefore is probably familiar to more people.
TT
And that is what I am looking for. I really don't want to write Enumerable.Range(5, 2).ToArray() to mean new[]{5,6,7}. I understand that 5.To(7) might be confusing, but it reads better than the Enumerable line. I am looking for suggestions that are more readable than 5.To(7)
Brian Genisio
Adding extension methods to something like int makes me feel a bit icky.
Benjol
A: 

You could look at something involving an enumerator and the yield statement?

Neil Barnwell
A: 

I think something like Set(1,100) or IntSequence(1,100) is easier to read than using an extension method.

Personal opinion though...

lc
I'd avoid "Set" because of it's meaning wrt:properties, and I'd prefer to see Sequence<int> than IntSequence
annakata
+5  A: 

I like the idea of using To. The alternative Enumerable.Range has a subtle flaw imo. The second parameter is not the value of the last element, it is the length of the enumeration. This is what I've done in the past:

public IEnumerable<int> To(this int start, int stop)
{
  while (start <= stop)
    yield return start++;
}

EDIT: If you want the result as an int[], just add .ToArray():

int[] theSet = 1.To(100).ToArray();
Lette
Yes, good point on the length, not value subtlety. I need it to be an array, not an IEnumerable, so yield doesn't gain me any benefit here. See my edits in the OP
Brian Genisio
You can do that, but you have really sacrificed readability when the set is generated...
Brian Genisio
Thanks for the comments. I reread the OP and realised that I had written exactly what you wrote... Sorry about that. :-)
Lette
This is a clever use of extension methods.
BobbyShaftoe
A: 

Your answer to your own question is fine. Just don't use a List if you are concerned about performance. Constructing a list and constantly expanding it is foolish. Just construct an array of the appropriate size. Use an extension method

public static int[] To(this int num)
    {
        //do work
    }
Brian Rudolph
A: 

I think you're worried too much that the language doesn't exactly express the particular syntactic thing that you want.

The way I see it, extension methods are a nice bit of sugar, but I wonder if you're really using it so much to justify the "surprise" of the extension method.

Within the domain of the language C#, it is more appropriate to spell out via the method name what you're trying to do. This feels more like Ruby than C#. This feels more like it wants to be in class by itself, especially if you wanted to add ranges with skip patterns (ie, the numbers from 1 to 10 by threes). I think that

public class RangedArray {
    public static int[] Generate(int from, into to, int by=1) { /* ... */ }
}

is a perfectly acceptable to express this in C#.

plinth
I agree. However, your default param is C# 4... confusing for some right now (pre rtm)
TheSoftwareJedi