Structs versus classes

In the first chapter, we created a basic Hello World program. In this topic, we will extend that program and use it to implement a struct and a class. While doing so, we will analyze the difference between the implementation and use of reference and value type variables. As you are already aware by now, a struct is a value type variable and a class is a reference type variable:

  1. Open the Console project created in Chapter 1, Learning the Basic Structure of C#, and declare a CoordinatePoint class with just two member attributes of x and y coordinates. Also create two constructors – one without any parameters and one with two parameters. Please refer to the following code implementation for this:
class CoordinatePoint
{
public float xCoordinate;
public float yCoordinate;
public CoordinatePoint()
{
}
public CoordinatePoint(float x, float y)
{
this.xCoordinate = x;
this.yCoordinate = y;
}
}
Please note that, in the preceding code, the use of the this variable is optional. It is used to refer to the current instance of the class and can be used to differentiate between class members and method parameters if they have the same name.
  1. Declare a similar structure. Notice that the compiler gives an error for the default constructor:
struct CoordinatePointStruct
{
public float xCoordinate;
public float yCoordinate;
public CoordinatePointStruct()
{
// This default constructor will give an error.
}
public CoordinatePointStruct(float x, float y)
{
this.xCoordinate = x;
this.yCoordinate = y;
}
}

As indicated in the preceding code, we will see a red label on the struct constructor. This is because, unlike classes, a struct cannot have an implementation of a default constructor. To remove the error, we need to remove the default constructor. On doing this, we will see that the compiler error goes away. The following would be the correct implementation of the struct:

struct CoordinatePointStruct
{
public float xCoordinate;
public float yCoordinate;
public CoordinatePointStruct(float x, float y)
{
this.xCoordinate = x;
this.yCoordinate = y;
}
}
  1. In the Main class, we will now declare two functions, one for each class and struct, respectively. In both functions, we will be passing a parameter by the name of obj, which is an object of type class and struct, respectively. In the same function, we will change the values of the x and y coordinate variables in both the struct and the class to a default value of 0.5F. The following is the code implementation for this:
static void ChangeValuesClass(CoordinatePoint obj)
{
obj.xCoordinate = .5F;
obj.yCoordinate = .5F;
}
static void ChangeValuesStruct(CoordinatePointStruct obj)
{
obj.xCoordinate = .5F;
obj.yCoordinate = .5F;
}

  1. Now, in the main function, declare the objects of both the class and the structure. Notice that, during the declaration of the respective objects, we are specifying the same values in the xCoordinate and yCoordinate member attributes.

For the sake of explanation, we will write syntax that will output the values in the respective member attributes to the console. The following is the code implementation for this:

Console.WriteLine("Hello World");
CoordinatePoint classCoordinate = new CoordinatePoint(.82F, .34F);
CoordinatePointStruct structCoordinate = new CoordinatePointStruct(.82F, .34F);
Console.WriteLine("Initial Coordinates for Class are :" + classCoordinate.xCoordinate.ToString() + " " + classCoordinate.yCoordinate.ToString());
Console.WriteLine("Initial Coordinates for Struct are :" + structCoordinate.xCoordinate.ToString() + " " + structCoordinate.yCoordinate.ToString());
  1. Now write syntax to call the respective ChangeValues function for each of structure and class. After the call to the function, have another statement to print the current values in the attributes of the struct and class objects.

Refer to the following code implementation for this:

ChangeValuesClass(classCoordinate);
ChangeValuesStruct(structCoordinate);
Console.WriteLine("Initial Coordinates for Class are :" + classCoordinate.xCoordinate.ToString() + " " + classCoordinate.yCoordinate.ToString());
Console.WriteLine("Initial Coordinates for Struct are :" + structCoordinate.xCoordinate.ToString() + " " + structCoordinate.yCoordinate.ToString());
  1. Click on Build | Build Solution and ensure that there are no compile-time errors.
  2. Click on Debug | Start Debugging. Alternatively, the user can also click on the F5 key or the triangular icon next to Start to launch the debugger. Please refer to the following screenshots:

Notice that the console shows the following output:

Notice that, after calling the change function, the value of the class object gets modified. However, there is no change to the values in the struct.

This is due to the fact that struct is a value type variable. Therefore, any change in the object, outside the scope of the function, has no impact as the change happens at an entirely different object in memory.

On the other hand, class being a reference type variable is affected by changes happening outside the scope of the function as well. For this reason, changes are propagated back to the main object as well.

To summarize, the following table illustrates the main differences between a struct and a class type variable:

Feature Class Struct
Default Constructor If a class does not have a constructor, then whenever an object is created for the class, the default constructor triggers and sets default values against the member variables present in the class. The default values are set in accordance with the default values of the type of those member variables. In contrast to a class, a struct cannot have any default constructors. This means that the application doesn't assign a default value to the member variables of the struct.
Memory Implementation As illustrated in the previous code example, a class is implemented as a reference type. This means that the value of an object of class is persisted across different scopes of the program execution. As illustrated in the previous code example, a struct is implemented as a value type. This means that its value is not persisted across different scopes of the program.
Inheritance We will be exploring inheritance in detail both in this chapter as well as in the next chapter. However, a class in C# can inherit from other classes. In contrast to a class, a struct cannot inherit from other structs or classes. This implies that code reuse is slightly difficult in structs compared to in classes.

 

Based upon the preceding differences, depending upon the requirements, a developer can choose the right data type between a struct and a class.

In the next section, we will look at how an interface is implemented in a C# application.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.40.189