Design Guideline for C# Structs (C Sharp)

This article focuses on the design guidelines that has to be followed when creating and using structs in your C# code. Basically structures can do most of what classes do. However there are certain differences between both. To begin with, you have to know when you are recommended to use structs instead of classes.



When to Use Structures?

• If the instances are relatively small
• If the instance life-time is going to be very short
• If you are going to embed the instance into some other instances

Design Guidelines for Using Structures:

• Logically speaking, entire structure you design should represent one value.

• Size of the instance should be less than 16 bytes.

• The structure you design should be immutable.

• Structures cannot be inherited.

• Structures cannot be declared as static.

• When an instance of structure is passed as an argument to a method, it is pass by value and not pass by reference.

• One big difference between structs and classes is that structs is a value type and classes are reference types. Since structs are value types, allocating and deallocating them is not as expensive as it requires for reference types. However, assigning a structure to an object and vice versa requires boxing and unboxing to happen. This is a performance overhead. Hence use structures if and only if your requirement requires relatively less number of boxing and unboxing to happen.

• You should not explicitly define a default constructor for structure. C# compiler doesn’t allow you to do it. This is because during runtime, a constructor will run internally and all elements of the structure will be assigned with the default value. Consider the following code:


public struct sampleStruct{
int member1;
public sampleStruct(int data) {
member1 = data;
}
sampleStruct(){
Console.WriteLine(“Default Constructor”);
}
}

In this code, you have defined two constructors, one constructor with parameters and the other without constructors. Structures accept constructors with parameters. But the constructor without parameter is the default constructor and is not permissible. Hence the above code will end up in the compilation error “Structs cannot contain explicit parameterless constructors”

• Members of the structures cannot be directly initialized. Consider the following code:
struct sampleStruct {
int member1 = 10;
int member2 = 134;
}
In this code, you have created a structure called sampleStruct containing two data members that are initialized directly. Though directly initializing data members is acceptable in classes, it is not permissible in structures. On compiling the above code, you will end up in error “cannot have instance field initializers in structs”. This error will be repeated for each of the member initialization you do.

• Use IEquatable function on structures wherever appropriate. IEquatable function is available in System namespace. It is used to compare two value types and determine if they are equal. It does the same job as that of “equals” method. Since structure is a value type, you can use this IEquatable function to compare structures as well. The interface in IEquatable will eliminate the need for boxing and reflection when compared to “equals” method.

• Ensure that all data members of structure are in valid state before accessing them through instance. As already known, data members of structure are initialized to their default value. If you have one of its data member to be a string, then string will be null by default. Be careful when you perform any manipulations on the string value. Ensure that you do null check before manipulating it. Consider the following example:


public struct sampleStruct {
string member;
public sampleStruct(string data) {
member = data;
}
public Boolean compareString(string data) {
bool returnValue = false;
if(data != null && data.length>0) {
returnValue = member.Equals(data);
}
}
}
class testClass {
sampleStruct obj1 = new sampleStruct(“Sample”);
bool isEqual = obj1.compareString(“Sample”);
if(isEqual) {
Console.WriteLine(“Strings are Equal”);
}
else {
Console.WriteLine(“Strings are not Equal”);
}
}

Output of this example will be:

Strings are Equal

In this example, you have an assumption that the member is always initialized using the constructor defined above. Hence in compareString method, you performed null check for the parameter alone. What if you create an instance of the structure without calling the constructor above? Then member value will be null and you perform equals function on a null value thereby ending into a runtime exception. Modify the class testClass as shown below:
class testClass {
sampleStruct obj1 = new sampleStruct();
bool isEqual = obj1.compareString(“Sample”);
Console.WriteLine(“Comparison result is:”+ isEqual);
}

Now if you execute the code, you will end up in NullReferenceException.

To avoid this problem, modify compareString function as shown below:

public Boolean compareString(string data) {
bool returnValue = false;
if((data != null && data.length>0) && (member!= null && member.length>0)){
returnValue = member.Equals(data);
}
}

| Design Guideline for C# Structs (C Sharp) | Design Patterns – Its Importance and Types | How to Implement Proxy Pattern Using C# (C Sharp)? | How to Implement Singleton Pattern Using C# (C Sharp)? | Illustration of Abstract Classes of C# (C Sharp) with Examples | Illustration of Sealed Classes of C# (C Sharp) with Examples | List of Overloadable Operators in C# (C Sharp) | Usage of [ ] and () Operators in C# (C Sharp) | What is C# (C Sharp) Nested Type? |


“Amazon and the Amazon logo are trademarks of Amazon.com, Inc. or its affiliates.”

| Privacy Policy for www.dotnet-guide.com | Disclosure | Contact |

Copyright - © 2004 - 2024 - All Rights Reserved.