In this article, we show you how to iterate through the same statement using loops. C# includes several loops including the for loop, the do-while loop, and the while loop. All of these are common in C# programming. We then discuss arrays, which are variables that are used often with loop structures. We'll show you how to loop through array values and display them to your users.
The For Loop
The for loop is the most common in C#, and it's the most preferred. The for loop lets you define a variable used to control the loop and increment this variable until a condition is met. Once the condition is met, the loop ends.
Let's first take a look at the for loop template.
for (int j = 0; j < length; j++)
{
Code execution statements go here
}
The for statement has three parts. The first section (int j = 0) is where the variable that controls the loop is created. You can also use a variable that you've created in other parts of your code, and you can initialize and assign this variable any value as long as it's an integer that can be incremented during each loop.
The second section (j < length) evaluates the value of j during each iteration. We have "length" in the example, because you can also use an array's index length to control the loop. We'll get into arrays and loops later in the article.
The final section (j++) increments the j variable. The ++ increment operator adds one to the variable.
If the condition in the second section returns true, the for loop continues. As long as the condition returns true, the for loop continues no matter how many times iteration occurs. It's important to note that you must create code in your for loop logic to always meet the condition eventually. If the loop never meets the condition, you create what is called an infinite loop. An infinite loop continues and eats away at your computer's resources. The program eventually crashes, and sometimes the computer must be rebooted to recover. In other words, avoid infinite loops and test your code to ensure that your logic never causes one.
Let's take a look at a real-world example.
for (int j = 0; j < 10; j++)
{
Console.WriteLine("j is now equal to {0}", j );
}
The above code is a simple loop that iterates 10 times. Note that the j variable is initialized to 0, and then it's evaluated in the condition section. This loop continues until j is equal to or greater than 10. During each iteration, the j variable's value is displayed in the console.
The j variable isn't incremented until the loop runs once. If the condition in the second section doesn't equal true, then the loop never runs and code execution falls to the statements after the for loop's brackets. The result of the above code is that the j variable displays values 0 to 9 and then the for loop ends.
You can also use the greater than and equal to relational operators. Let's take a look at an example.
for (int j = 0; j <= 10; j++)
{
Console.WriteLine("j is now equal to {0}", j );
}
This simple logic change executes the for loop one additional time. It's important to note these subtle changes, because they can have major effects on your code. In this example, the j variable value is shown from 0 to 11.
The Do-While and While Loops
The do-while and while loops are not as common as the for loop, but they do serve a purpose. The while loop is much more popular than the do-while loop, so we'll focus on the while loop first.
The while loop is similar to the for loop, but it only uses one condition statement. Let's take a look at the while loop template.
while (condition)
{
Code execution statements go here
}
The while loop looks like the if statement from the last chapter, but the difference is that the while loop continues to iterate as long as the condition evaluates to true. The while loop has a greater chance to create an infinite loop, so ensure that you test the code to ensure that the condition is eventually met in all scenarios.
Let's take a look at an example.
int num;
num = 1;
while (num < 20)
{
Console.WriteLine(num);
num++;
}
One reason coders prefer the for loop is because you can initialize the iteration variable within the loop itself. Notice in this code, we first define a variable and then assign a value to it. We decide to start the iteration at the value of 1.
In the above example, the while condition is first verified and evaluated. If the condition results in a value of false, the while loop is skipped. You can see from the sample code that the while loop's condition returns true since the variable is assigned an initial value of 1. The while loop goes through its first loop.
Another reason why the while loop is problematic is that the coder is responsible for ensuring that the variable is incremented in the code. Notice that we have a Console.Write statement, and then we have a num++ statement to increment the variable. If we forgot to place this increment statement in the while loop, the loop would never end. You essentially create an infinite loop that crashes the program and possibly the computer.
Since the loop condition indicates that the loop should execute until the num variable is equal to or greater than 20, this loop prints values 1 to 19 on the screen.
The do-while loop is similar to this statement, except the do-while loop always executes its statements at least once. Because the condition in the do-while statement is after the execution block, the condition isn't evaluated until the code is executed once. Let's take a look at an example.
int num;
num = 1;
do
{
Console.WriteLine(num);
num++;
} while (num < 20);
We used the same variables and condition logic as the while loop. We create a variable named num and assign it a value of 1. We start the do-while loop with the "do" statement and then add brackets for the statement. Notice that there is no condition at the top of the do-while loop, so the statements in brackets execute. Only after they execute once is the condition then evaluated. The do-while statement also requires a semicolon to terminate the loop. This loop is the only one that requires a semicolon after the condition parenthesis.
After the first loop, the condition is evaluated, which in this example evaluates to true. The num variable was initialized with the value of 1, but we increment the variable within the brackets. Therefore, the num variable has the value of 2 when the condition is evaluated for the first time. This logic difference is important when you create larger, more complex programs. In this example, the values 1 to 19 still display as output.
All three of these loop types are common in C# programming. Practice with some of the code to view the differences in logic and output.
Arrays
Arrays and loops go hand-in-hand because loops are used to display or store the values in an array. You could make a variable for each value that you need to store, or you can make your code more efficient and create one variable that contains several values.
You first need to initialize the array to use it in your code. You can initialize an array in two ways. The first way defines the array but does not fill it with any values. The second way initializes the array with some values. Let's take a look at both ways.
string[] colors;
string[] colors2 = new string[3]{ "Red", "Blue", "Pink" };
In the above code, we create two variables named colors and colors2. The first initialization doesn't define the array's values, so you can add them later in your code. You're also not bound to a specific number of values.
The second variable colors2 is initialized with values assigned to it. In this example, we define the array with 3 values. We then assign those variables. Each of them is separated with a comma. Notice that the index numbers in an array always start at 0. This means that defining an array with 3 values means indexes 0, 1, and 2 are assigned to the values. Index 0 is given to the first value "Red," index 1 is given to the second value "Blue," and 3 is assigned to "Pink."
We assigned values to colors2, but you now need to assign values to the first colors variable. We use the indexes to assign values. Since we didn't define an array length, we aren't limited to the number of values that can be stored in the variable. Let's assign 2 values to the first variable.
string[] colors;
string[] colors2 = new string[3]{ "Red", "Blue", "Pink" };
colors[0] = "Purple";
colors[1] = "Green";
In this example, you'll see that we define which indexes are assigned values for colors. If you attempted to add a value to colors2, you would receive an error since you limited the array to only 3 values.
In the above example, the array is a 1 dimensional. C# allows you to create multidimensional arrays, which you could use to put these values together in one variable. A multidimensional array is a way to store values in different dimensions similar to a graph. The following is a visual representation of a multidimensional array.
string[,] colors = { { "Purple", "Green" }, { "Red", "Blue", "Pink" } };
When you think of how these values are stored, think of them as a list of rows and columns. The first set is the rows. The second list is the columns.
colors[0][0] colors[0][1] colors[0][2]
colors[1][0] colors[1][1] colors[1][2]
Using the above graph, you know that the value at 0,0 is "Purple." Therefore the following code prints "Purple" to the screen.
Console.WriteLine(colors[0][0]);
Multidimensional arrays are often difficult to understand, so they are rarely used in code. The above array is 2 dimensional, but you can have several dimensions in your code. Since multidimensional arrays are difficult to debug and review, most coders look for other ways to write code that's more efficient and can be more easily maintained.
In most cases, you won't know the values of your array until after you define it. Think of querying a database. You create the array but then you need to fill it with the values you've retrieved from a database. This means that using the statically defined way of creating arrays wouldn't work for you. You need a way to populate an array dynamically even if it's 100 values stored in the variable. You can have 1 or thousands of values stored in an array, although too many values should be a concern. Remember that the compiler reserves memory for an array and each of its values. Avoid using arrays with thousands of values, because it can consume too much memory and crash the machine.
We can use the loop structures to fill the array with values. The for loop is preferred when dynamically filling an array with values. You can use the length of the array to set the condition, so you always iterate the exact number of times in your code. If you attempt to access an array value that doesn't exist, the program returns an out-of-scope error and your program crashes.
Let's see how you can populate an array using a for loop. We'll use colors2 to populate values in colors.
string[] colors;
string[] colors2 = new string[3]{ "Red", "Blue", "Pink" };
for (int j = 0; j < colors2.Length; j++)
{
colors[j] = colors2[j];
Console.WriteLine("The value in colors{0} is {1}", j, colors[j] );
}
We use the same array variables as previous examples. We then add a for loop that iterates through each value in the colors2 variable. Notice that we use the colors2.Length property in the for loop condition. Length is a C# property available for any array. It returns the length of the array, which is the number of values stored. In this example, the number of values is 3. It's important to use the greater than comparison operator when using the Length property. If you use the greater than or equal to (<=) condition, the loop will continue when j reaches 3. You have 3 values, but remember that they are labeled with indexes 0 to 2. If you attempt to use index number 3, your program will return an error.
The for loop uses the j variable to access indexes in both the color and the colors array. For instance, j has the value of 0 during the first iteration. Therefore, the color "Red" is assigned first since it's located at the first position of the array. The loop continues until the condition is met. In this case, once j reaches the value of 3, the loop exits.
We also print the result of the iteration to the user's screen. You can run this code to see the loop for yourself.
You can also use the while loop to assign values to your variables. Let's take a look at the while loop that also performs the same process.
int j;
j = 0;
while (j < colors2.Length)
{
colors[j] = colors2[j];
Console.WriteLine("The value in colors{0} is {1}", j, colors[j] );
j++;
}
The above method is less preferred, because you need to create the variable for your condition separately, and you must remember to increment when you create the loop. With the for loop, the increment logic is a part of the condition statements, so you can't accidentally create an infinite loop.
Loops and arrays are a more complex concept, but you can master them with practice. The biggest difficulty for most coders is the logic behind the loops. These loops are critical parts of your program and they define much of the program's logic. Ensure that you always test your program for any logic flaws in your loops before compiling it.
Generic Types and Lists
In some cases, you won't know what data type you need, and that's where generic types help with programming. With generic types, you can create variables that don't have a data type until you need them. To use generic types, you need to create your own generic classes.
After we review generic types, we'll review lists. Lists are similar to arrays, but the List class in C# lets you do much more in a list than you can do in a standard array. Lists are common in both web development and desktop development in C#. They let you store several objects, and they can be class objects and not just primitive types. You can even make generic lists.
We'll cover both of these topics in detail, so you can practice more with generic types and lists in your programming projects.
Generic Types
Generic types give you more flexibility when you define your variables. Instead of being tied to a data type when you create a variable, you can use a generic and send the data type during run-time.
To use generic types, you must create a class that handles the storage of the data. The class takes a dynamic data type and then stores the values in an array. The character T indicates to the compiler that you want to create a generic type.
Let's first take a look at the creation of a generic type class.
public class MyGeneric<T>
{
}
We are only showing you the basic class definition without the constructor or any of the methods. The T character hasn't been seen yet in this article. The T indicates that it's a generic data type that will be passed to the class. We don't know what the type will be until the class is instantiated.
Notice the syntax is MyGeneric<T>. The MyGeneric section is the name of class and the <T> syntax indicates that you want to create a generic type class. Basically, the "T" is the giveaway in any C# code that you're creating a generic data type.
You can create any methods in your new generic type class, but three are necessary to instantiate and use the class object. First, you need the constructor. We review constructors in previous chapters. The second is a method that stores the values you send to the class in a member variable array. The third is a method that lets you retrieve these values from the array.
Before you start using generics, you also need to add a library at the top of your code. We'll add this library at the top of the code examples. If you create a new C# coding file using Visual Studio, this library should be automatically added at the top of the page.
Let's first take a look at a generic type constructor.
using System.Collections.Generic;
public class MyGeneric<T>
{
private T[] array;
public MyGeneric(int size)
{
array = new T[size + 1];
}
}
We first create an array with the type T. Remember that any reference of the type T indicates to the compiler that you're creating a generic. If you recall from Chapter 7, we discussed how to make array variables. The modifier sets whether the array is private or public. We don't want other classes to manipulate the member array directly, so we make it private. The second statement indicates that we're creating an array of type T. The brackets after the T indicate that the variable is an array. And finally, the "array" statement is the name of the array variable.
The generic array is meant to store any values passed to the class. We first create a constructor that determines the size of the array and creates a new array instance. This is necessary when working with generic arrays and classes. Since we define only one constructor and it requires a size, the instantiation statement must set a size to use the generic class.
We can see how the class instantiation works. The following code properly instantiates the generic class.
MyGeneric my = new MyGeneric <int>(3);
Notice that we instantiate the class in the same way we do with others, but we pass a data type where the class indicates a T. Even though the class is generic, you still need to give it a data type during execution. This is the benefit of a generic data type – you don't need to initially set a data type, but you do when you finally decide to use the class. In this example, we decide to use the integer data type. Notice in the parameters, the number 3 is used. This tells the generic MyGeneric class to initialize an array that can store 3 values.
Instantiation of the class works and the syntax is valid, but the class has no methods and doesn't allow you to store any values. Let's add a method that stores values we pass to the class.
using System.Collections.Generic;
public class MyGeneric<T>
{
private T[] array;
public MyGeneric(int size)
{
array = new T[size + 1];
}
public void SaveItem(int index, T value)
{
array[index] = value;
}
}
In the above example, we added a method called SaveItem. This method lets us store values in the array as we build it. You can send the method one value at a time. As you can probably guess, you can also create a method that stores several values at a time, but it would take much more code to ensure that you don't accidentally overwrite previously stored values. For simplicity, we're going to work with one value at a time.
We need to pass the SaveItem method the index location for the array and the value that should be stored. Notice that we store the value in the local class member array.
Now, let's see how we can store values using the new method.
MyGeneric my = new MyGeneric <int>(3);
my.SaveItem(0, 5);
We still need to instantiate the class and define the data type we want to use. Notice that instantiation is the same as we used previously. Next, the SaveItem method is called. We set the parameters needed in the class definition. The first parameter in the SaveItem method is the index location in the array. Since this is the first item stored, a value of 0 is used. The second parameter is the value we want to store. In this example, we store the value 5 in the array's first index location.
We can store values in the array, but we have no way of retrieving what was stored. The last necessary method needed is the GetItem method. This method retrieves a value and stores it in a variable. Again, you can create two GetItem methods. One would retrieve one value, and the next would retrieve all values. To keep the sample code simple, we'll use only a method that retrieves one value.
Let's add the final method to our class.
using System.Collections.Generic;
public class MyGeneric<T>
{
private T[] array;
public MyGeneric(int size)
{
array = new T[size + 1];
}
public void SaveItem(int index, T value)
{
array[index] = value;
}
public T GetItem(int index)
{
return array[index];
}
}
The MyGeneric class now as the GetItem method. This method is used to retrieve values stored with the SaveItem class. The method takes an integer parameter that indicates which value you want to return. Let's take a look at how you can call both methods in your code.
MyGeneric my = new MyGeneric <int>(3);
my.SaveItem(0, 5);
my.SaveItem(1, 4);
my.SaveItem(2, 3);
int storedValue = my.GetItem(2)
Console.WriteLine(storedValue);
In the above code, the MyGeneric class is instantiated. We indicate that we want to store 3 integer values. We then use the SaveItem method three times to store three values in each index. Using the GetItem method, we then retrieve the value in the second index. Remember that array indexes start at number 0, so the value stored at index 2 is actually the third value. In this example, the number displayed on the screen is 3.
You'll use generic data types when you don't know what you want to store in an array until the code is executed. For instance, you might take numeric and string values from users. You don't know what data type the user will enter until the data is actually entered. You would then use a generic class to store values after you identify the user's input type. This type of dynamic coding gives you much more flexibility when working with unknown data formats.
C# Lists
A list is a generic data type class provided to you by the .NET framework. Instead of creating your own generic classes, you can use the List library. This library has the store and retrieve methods already defined, so you don't need to manually create them. Lists also have several other useful functions that let you manipulate a group of values dynamically.
Let's first take a look at how you create a List object.
List<string> colors = new List<string>();
colors.Add("red");
colors.Add("blue");
colors.Add("pink");
Notice that instantiating a List class is the same as instantiating our custom generic object. The class name is List, and we send the string data type to the class. The List class does not require any parameters like our MyGeneric class, so no parameters are passed.
Instead of the SaveItem method in our MyGeneric class, the List class has the Add method. This method is used to add values to the array. In this example, we add three string color values.
If you recall, we mentioned that our MyGeneric class was missing a way to add multiple values, but we wanted to keep the code simple. With the List class, we can add an array of values to the List. The AddRange method adds several values at once. Let's take a look at the code.
List<string> colors = new List<string>();
string[] array = new string[] { "red", "blue", "pink" };
colors.AddRange(array);
That's it. You don't need to specify the number of indexes needed. You just need to send the List class variables that you want to store.
Our MyGeneric class didn't have a way to remove items, but the List class does. The List class has the Remove method and the RemoveAt method. The Remove method deletes the first instance of a given value, and the RemoveAt method removes a value at a specific index number.
First, let's take a look at the Remove method. Suppose we want to remove "red" from the list of colors. The following code removes it.
List<string> colors = new List<string>();
colors.Add("red");
colors.Add("blue");
colors.Add("pink");
colors.Remove("red");
The Remove method removes the "red" value and then automatically shifts the rest of the values up the index list. In other words, "blue" is now in position 0 and "pink" is in position 1. If you have multiple values of "red" in the List, the Remove method only removes the first value found.
In some cases, you need to remove a value at a specific index location. Suppose you want to remove the last value, which is at index location of 2. Let's take a look at the RemoveAt method.
List<string> colors = new List<string>();
colors.Add("red");
colors.Add("blue");
colors.Add("pink");
colors.RemoveAt(2);
That's all it takes to remove values.
The List class has several more beneficial functions. It also allows you to sort values. Suppose you want to sort your string values in alphabetical order. If you used your own generic class, you'd need to create the sort method manually. Instead, you can use the List sort method without any effort. Let's take a look at the Sort method in action.
List<string> colors = new List<string>();
colors.Add("red");
colors.Add("blue");
colors.Add("pink");
colors.Sort();
foreach (var name in colors)
Console.Write(" {0}", name);
The output from the above method is the following.
blue
pink
red
As you can see, the List class is a powerful generic class that makes it much easier when you need to work with several values. You can even reverse values in the list. Suppose we accidentally added the list in the wrong order, and now we need to reverse the way the colors are stored. We can use the Reverse method. Let's take a look at what this method works.
List<string> colors = new List<string>();
colors.Add("red");
colors.Add("blue");
colors.Add("pink");
colors.Reverse();
foreach (var name in colors)
Console.Write(" {0}", name);
The output from the above method is the following.
red
pink
pink
In many cases, you need to know the number of values stored in the List. Suppose you retrieve a list of unknown values from users. You don't know the number of values entered by the user, because you don't require a minimum or a maximum. You need to work through the list based on the number of values. You can use the Count method. This method gives you an integer count value.
Let's see the Count method in action.
List<string> colors = new List<string>();
colors.Add("red");
colors.Add("blue");
colors.Add("pink");
int count = colors.Count();
Console.Write(" {0}", count);
A value of 3 is displayed on the screen.
The List class has several comparison operations that you can use to find values within the array. For instance, suppose you want to know if a specific value is present in the List. You can use the Contains method. This method is similar to the String class that also identifies if a value is present in a string.
The following code shows you how to find a value in a string using the Contain method and the if statement.
List<string> colors = new List<string>();
colors.Add("red");
colors.Add("blue");
colors.Add("pink");
if(colors.Contains("pink"))
{
Console.Write("This list contains the value of pink.");
}
The above code uses the Contains method to search through the list of values and identify if it exists. In this example, we search the list of values for the string "pink." Since we know that that value "pink" does indeed exist in the List, we know that the if statement's condition returns true. Since the condition results in a value of true, the string "This list contains the value of pink" displays on the screen.
The List class has several useful methods, but the last one that we'll cover is the ToArray method. This method lets you turn the List into an array and store it in your own variable. Let's take a look at the code.
List<string> colors = new List<string>();
colors.Add("red");
colors.Add("blue");
colors.Add("pink");
string[] colorArray = colors.ToArray();
In the above code, the List class takes care of the retrieval process and turns all values into an array. The array is then stored in the colorArray variable we created.
Generic lists give you much more flexibility when you work with user input. You can create your own, but the List class makes it much easier and saves time coding.