The C# language is made up of variables and data types. Variables hold your values. You can either store that value in a database or display it to the user. Each variable has a data type, and you're bound by syntax rules to only store a value that corresponds with its data type. This article uncovers variables and data types associated with these variables.
What is a Variable?
A variable is a container for a value. To be even more precise, a variable is an allocated space in computer memory that stores your value. Variables are used to identify values in a friendly way instead of reference memory addresses.
Each variable has a specific type defined when you create the variable. Once you initialize a variable with a specific data type, you cannot store an alternative data type. For instance, you can't store a string value in a variable that you've defined to only store numbers.
Variables don't just store basic data types. Basic data types are also called primitive data types, but variables can be much more complex than just a number or a character. Variables can be enumerators, structures, classes, and lists. We'll cover the primitive data types initially and discuss the more complex types in later chapters.
Variable Types
Variables can be several different data types. The primitive data types include:
-
Floating points
-
Decimal
-
Boolean
-
Strings
For anyone who has coded in other C language, you might be confused by the floating point variable and the decimal variable. A decimal data type holds a standard decimal number such as 123.456. A float data type stores a binary decimal value such as 10101111.00111.
Booleans are the "true" and "false" values in C#. Actually, these values stand for a 1 or a 0. A 1 means true and a 0 means false. However, in your C# code, you type "true" or "false" for your Boolean values.
Strings are an array of characters. Note that there is a difference between a "String" data type and a "string" data type. String – with the capital S – is a C# class. The string data type – lower case's – is a primitive data type. You can do much more with the class String, but it's generally frowned on by experienced developers to use the String class when the primitive data type can be used instead.
Let's take a look at how you can define and initialize a variable. Initializing and defining are two distinct processes in C#. First, take a look at a simple variable definition.
int mynumber;
string mystring;
In the above code, two variables are defined. They are not initialized, because they have no value assigned to them. The first variable named mynumber is defined as the int data type. You can only assign an integer value to this variable, which means any character or decimal value is rejected. If you attempt to assign an alternative data type value to the integer variable, the compiler gives you an error, and your code won't compile.
The second variable is a string named mystring. This variable can only hold a string. Remember that strings are an array of characters, so technical the variable holds a character array.
Data type definitions are important in computer memory management. When you create a variable, the computer allocates memory for the value. We don't know the value yet, but memory is set aside for it. If you attempt to store a value that doesn't match the data type, you attempt to store too many bytes. The result is an overflow and a crashed program.
Using the above two variables, the mynumber variable uses 2 bytes, and the string variable mystring has 10 bytes set aside for it. 1 byte is 8 bits, but memory is allocated in 8-bit blocks.
Defining a variable without initializing it causes memory usage issues. An integer is always 2 bytes, but a string without an initialized value is variable length. Since the compiler doesn't know the length of the string, it sets aside 10 bytes to ensure that it has enough memory allocation. When you initialize the string with a value, however, the amount of memory set aside is equal to the string length. This can greatly improve your program's efficiency and memory management.
Let's take a look at the same variables except with proper initialization.
int mynumber = 1;
string mystring = "Hello";
The above code is preferred when you create variables. We've initialized mynumber with a value of 1, and the mystring variable is set to "Hello." In some cases, you won't know the value of a string when you initialize it. You could choose to define it without initialization like we used in the previous section, or you can use the special "string.Empty" assignment. Let's take a look at string.Empty.
int mynumber = 1;
string mystring = string.Empty;
The above code is much more efficient when you don't know a string's value. This sets the string as an empty zero-length string. When you define a string without a value, it initializes to null. Null values can cause bugs and issues in your code. Some static functions called on a null string will fail, but they don't fail with a zero-length string. It's another reason why initializing a string with a value is preferred.
The following list is a few more rules for C# variables.
-
Variables are case sensitive. This means myVariable, MYVARIABLE, MyVariable, and myvariable are all different variables. It's standard practice not to use the same name even with different case characters.
-
Variables cannot have the same name within the same scope.
-
Variables must start with an underscore or a character.
-
Variables cannot contain special characters or spaces.
-
Variables cannot use reserved keywords for the C# language.
Variable Scope
Variable scope determines where you can access a variable in your code. To understand scope, we must introduce some advanced concepts, but we'll discuss these concepts in detail in future chapters.
Variable scope is important in functions and classes. When you create a variable within these types, you can only obtain their values within the class or function in which the variable is defined.
Let's take a look at a C# function to illustrate the concept.
void HelloWorld()
{
string mystring = "My Hello";
string callingstring = main();
}
string main ()
{
string mystring = "Hello";
return mystring;
}
In the above code, we have two functions named main and HelloWorld. We're assuming that HelloWorld runs when we start the program. In HelloWorld, we call the main function.
You'll notice that we have the same name for two different variables in both functions. In the previous section, we mentioned that variables could not have the same name within the same scope. In these two functions, each variable is out of scope to trip a compiler error.
When you create a variable within a function, its scope remains within the function. These variables are also called local variables. Once the function completes each line of code, the variable is destroyed in memory. For this reason, you can't access the variable outside of the function's scope.
In the first function, we create the string mystring and assign it a value of "My Hello." Then, we call the main function to retrieve the value of mystring in the main function. The main function returns its own mystring value to the calling statement. The calling statement then assigns the value to the callingstring variable. This is how you get around the variable scope rules and obtain values within other functions. We'll discuss functions (also called methods in classes) in chapter 8.
What happens when you need a variable available outside of the function? You can create a variable called a global variable. Global variables are available in any area of your code regardless of where you call the variable. While global variables are common in other languages, C# uses static variable designation to create global variables for your code.
The previous variables are also standard variables, so they are dynamic and can be changed as your code executes its statements. What if you have a variable that should never change its value? For instance, the value of Pi always remains 3.14. It should never change, and you want to block any code that attempts to change its value. You perform this action by defining your variables as a constant.
Constants are usually defined in a static class, which introduces two more concepts. Classes are containers that define their own data type. For instance, if you have an ecommerce store, you need a customer and an order class. These two classes define the actions and characteristics of each component. The employee class defines an employee's first and last name. It defines methods that create a new customer and add a customer note. Properties are the characteristics or "nouns" for a class. Methods are the "verbs" or actions defined within the class.
Static classes are those that don't need to be instantiated. Instantiation of a class is similar to initializing a variable. You need to define the data type for a variable. The variable then contains all aspects for the variable. With a class, you create your own data type that you then use to define the variable. The variable allows you to work with the class variables, methods, and other objects. Static classes ignore the instantiation rule and allow you to use class variables and methods without first assigning it to a variable.
Let's take a look at a static constant class that defines a value for Pi.
static class Constants
{
public const double Pi = 3.14159;
}
The above code defines a class called Constants. We've also defined this class with the static type. We've combined two concepts in this line of code – a global variable since it's defined as static, and a constant that will never change its value. This is the standard way you create constants in your programs, but some developers create constants directly in a class.
The static type is how you tell your code that you don't want to force other classes to instantiate a variable to use the class. Every statement within the class brackets is a part of the Constants class.
We have some modifiers and a data type that defines the variable Pi. The "public" modifier tells the compiler that the variable can be accessed outside the scope of the class. You can also set a variable to "private," which blocks other classes from accessing the variable value. Private variables can still be accessed from within the class, but they can't be accessed outside of the class even in derived child classes.
The next modifier is the "const" statement. This keyword is what sets the variable to a constant type. Constants cannot be changed. If you attempt to change the value of Pi, the compiler returns an error.
Next is the double data type. The double data type is a decimal data type, which we need for the Pi variable. You could use the decimal variable type if you decide to use more precision for Pi. The double data type does not allow for as many precision points as decimal. Since we only use 2 precision points in our Pi variable, we save some memory and define the variable as a double instead of a decimal data type.
Instance Variables
The final type of variable we need to discuss is the instance variable. An instance variable is a part of a class. Classes usually have several instance variables.
For instance, you could have an Employee class as a part of your ecommerce website. Instance variables are used to define the characteristics of the Employee class. They are the "nouns" of the class. They describe the employee's first and last name, the date of birth, and the gender. Of course, you could have dozens of additional characteristics in your Employee class, and each one would be its own separate instance variable.
Let's take a look at some code.
class Employee
{ string m_firstName;
string m_lastName;
DateTime m_birthDate;
string m_gender;
public void DisplayName()
{
Console.WriteLine(m_firstName);
}
}
The above class is named Employee. You always know when a class is created by the "class" modifier. Within the class brackets is all code associated with that class. In this case, the class contains four member variables or instance variables. The "m_" prefix is common with C# coders, because it indicates that the variable is a member variable of the class.
We haven't initialized values for the class, but you can also assign member variables a default value. You can also define a member variable as a class variable. Notice the DateTime variable is a class data type. DateTime is a class that deals with dates and time functions, so it's better to declare any variable that needs date functionality with this class data type.
We also have a member function in the class. Member functions are also called methods, which we will cover in Chapter 8. This function is set to public, so it can be used outside of the class itself. Since the class is not set to static, you need to instantiate it before you can use it in your code. This class does not have a constructor, so it can't be instantiated. We'll also cover instantiation in Chapter 8.
The takeaway from the class is the instance variables, and the function that displays the value of the variable to the user. This member variable is within scope even though the member variable is called in the function and defined outside of the function. When you work with classes, member variables are available to member functions.
We covered several variable concepts in this chapter. Each of them is important when you get started with C#. Variables are one of the main foundations of any program, so learning concepts in the C# language will help you better understand other languages.