Use Of Range, Repeat And Empty In LINQ

Introduction

Here, we are going to see the uses of the Range, Repeat and Empty keywords in LINQ and we also will discuss their differences.Let's move to the detailed explanation. 

Prerequisites
  • Visual Studio
  • Basic knowledge of LINQ
Article Flow
  1. What is Generation Operator? 
  2. Use of Range
  3. Use of Repeat
  4. Use of Empty
  5. Difference between Range,Repeat and Empty 
What is Generation Operator

If you have done any non-trivial amount of work with C#, you will be familiar with LINQ becasue it provides a set of extension methods. While the Select, Where, Any, and more extension methods are basically well known, the Enumerable static class also offers three non-extension methods to us below,
  • Empty<T>()
  • Range()
  • Repeat<T>()
These allow us to the create some common type of sequence, array or collection using a single expression, rather than creating lists manually and populating them using loops. This means those methods return a new sequence that implements the IEnumerable<T> interface without requiring that a similar sequence is provided beforehand. Okay! Now we move on with an example to get a clear picture about this.

Use of Range 

This is a static method of the Enumerable class and it's used to create a set of sequential integers. 

"Range" Overloads the following method

public static IEnumerable<int> Range(int start,int count)

Range Accepts only the integer as input parameter, and it contains two parameters. In the above method the first parameter represents starting elements of the integer and the second parameter represents the limit of sequence. Okay now let's move to the example to get more idea of this unique functionality
  1. IEnumerable < int > rangeSequence = Enumerable.Range(50, 8);  
  2. Console.WriteLine("Total Count of Element / Index : " + rangeSequence.Count() + System.Environment.NewLine);  
  3. for (int i = 0; i < rangeSequence.Count(); i++) {  
  4.     Console.WriteLine("Value at index {0} : {1}", i, rangeSequence.ElementAtOrDefault(i));  
  5. }  
Result

 
 
In result we can see the 50 is the starting index / element value and 8 represented how many elements are needed to create including starting element 50. Now we got the basic knowledge about range, let's move to another example to get deep knowledge on this.

Now we are going to see the list of the first 5 even numbers, we can start with the number of expected items and multiply up by our step needs in a Select(),

example
  1. var evens = Enumerable.Range(1, 5).Select(n => n * 2).ToList();  
  2. foreach(var item in evens) {  
  3.     Console.WriteLine("Even Number :" + item);  
  4. }  
Here we can directly convert the generation operator result into the Tolist, Toarray,ToString,Tolookup. For our needs I converted the result into the list.

Result



How it Works ?

n=>n* 2 work as (1*2,2*2,3*2,4*2,5*2), we mentioned the starting element is 1 and elements we need to create is 5.

Shall we see integer as a result, and how to return the string?
  1. //here we knew the result type so i used to the string, use the var while do not know about the result   
  2. IEnumerable < string > rangewithString = Enumerable.Range(1, 5).Select(i => (i * 10) + " " + OurLogic(i)).ToArray();  
  3. //or var rangewithString = Enumerable.Range(1, 5).Select(i => (i * 10) + " " + OurLogic(i)).ToArray();  
  4. foreach(var item in rangewithString) {  
  5.     Console.WriteLine(item);  
  6. }  
  7. private static string OurLogic(int i) {  
  8.     string result = string.Empty;  
  9.     switch (i) {  
  10.         case 1:  
  11.             result = "1st";  
  12.             break;  
  13.         case 2:  
  14.             result = "2nd";  
  15.             break;  
  16.         case 3:  
  17.             result = "3rd";  
  18.             break;  
  19.         case 4:  
  20.             result = "4th";  
  21.             break;  
  22.         case 5:  
  23.             result = "5th";  
  24.             break;  
  25.     }  
  26.     return result;  
  27. }  
Result

 

Here we saw how to repeat the same action for a certain time, now we got the clear idea about Range(), it's used to generate a range of integers from a given start value and for a given count.

Still we have seen the positive flow, when does it fall into exception?
 

Now The Enumerable.Range method will throw an ArgumentOutOfRangeException if either count is negative or start + count - 1 is larger than int.MaxValue. 

Use Of Repeat 

Repeat Method is used to generate a collection of IEnumerable<T> type with a specified number of elements and each element contains same specified value. 

"Repeat" Overloads following method 
  1. public static IEnumerable < TResult > Repeat < TResult > (TResult element, int count)  
First Parameter "TResult element" represents -> the value to be repeated

Second Paramter "int count" represents-> Number of times needed to repeat the generated element of sequnce. Shall we move to the example to get clear picture about this?
  1. IEnumerable<int> repeatColloction = Enumerable.Repeat<int>(10, 10);  
  2. Console.WriteLine("Total Element Count: " + repeatColloction.Count());  
  3. for (int i = 0; i < repeatColloction.Count(); i++)  
  4. Console.WriteLine("Value at index {0} : {1}", i, repeatColloction.ElementAt(i));  
Result

 
 
Here we can see the total element count is 10 and we metioned the 10 as first parameter and said to repeat the same element 10 times. Now shall we try the same method we tried in Range to call the same action to all elements.
  1. IEnumerable < string > repeatwithString = Enumerable.Repeat(1, 5).Select(i => (i * 10) + " " + OurLogic(i)).ToArray();  
  2. foreach(var item in repeatwithString) {  
  3.     Console.WriteLine(item);  
  4. }  
  5. private static string OurLogic(int i) {  
  6.     string result = string.Empty;  
  7.     switch (i) {  
  8.         case 1:  
  9.             result = "1st";  
  10.             break;  
  11.         case 2:  
  12.             result = "2nd";  
  13.             break;  
  14.         case 3:  
  15.             result = "3rd";  
  16.             break;  
  17.         case 4:  
  18.             result = "4th";  
  19.             break;  
  20.         case 5:  
  21.             result = "5th";  
  22.             break;  
  23.     }  
  24.     return result;  
  25. }  
Result

 

Here it returns the same value (1*10) five times, and it's called the mentioned method OurLogic() for each sequence element. Still we have seen the positive flow, shall we see the Negative flow of repeat Method?
  1. IEnumerable<int> exceptionRepeat = Enumerable.Repeat(1, -3).ToList();  
 

We can see the exception, Repeat method fall into the ArgumentOutOfRangeException while the Count(Second Parameter)value is negative.

Now we have a clear picture about Repeat Method, It's used to generate a sequence that contains one repeated value.

Use of Empty 

The Empty() method is just used to returns an empty collection of a specified type. No standard parameters are used by this method but the type T of the resultant IEnumerable<T> must be mentioned there.

"Empty" Overloads the following method
  1. public static IEnumerable<TResult> Empty<TResult>()  
The Empty<TResult>() method caches an empty sequence of type TResult. When the object it returns is enumerated, it yields no elements.

Shall we move on with the example
  1. var emptystringCollection = Enumerable.Empty<string>();  
  2. var emptyClass = Enumerable.Empty<TestClass>();  
  3. Console.WriteLine("Count of String: {0} ", emptystringCollection.Count());  
  4. Console.WriteLine("Type: {0} ", emptystringCollection.GetType().Name);  
  5. Console.WriteLine("Count of TestClass: {0} ", emptyClass.Count());  
  6. Console.WriteLine("Type: {0} ", emptyClass.GetType().Name);  
Result

 

The main advantages of empty is "Even if you use empty array or empty list, those are objects and they are stored in memory". Then Garbage Collector has to take care of them. If you are dealing with high throughput application, it could be noticeable impact.

Enumerable.Empty does not create an object per call thus putting less load on GC.

Difference between Range,Repeat and Empty

 Range Repeat Empty
 Generates collection of IEnumerable<T> type with specified number of elements with sequential values, starting from first element. Generates a collection of IEnumerable<T> type with specified number of elements and each element contains same specified value. Returns an empty collection
 
Summary

In this article we learned about use of Range, Repeat and Empty and their differences. I hope it's helped you; your feedback and comments are always welcome.