What you did not know about Structs in C#
What is the difference between structs and classes in C#?
I have asked this question in most of the interviews I have taken and most people give the following standard answer:
"They are exactly like classes but they don’t support inheritance."
"That’s it?"
"Uh huh… more or less."
"A lot less than more" I told myself
Actually there are several more subtle differences which you, as a programmer, should know. We shall cover the important ones in this edition.
Structs do not support inheritance nor can they be used as the base for inheritance for a class. Please note that (ironically) all struct types implicitly inherit from System.ValueType.
A struct is a value type whereas a class is a reference type. So when you create an instance of a structure, the instance is created on the stack. You can use the new keyword with a struct but its not for the reason you think.
You cannot declare a default constructor for a struct. This is a very interesting ‘gotcha’. We shall soon see why.
You can create an instance of a struct using the new keyword or even without it.
The reason for the above two statements are as follows: When you create a struct, the compiler automatically creates a default constructor for you and where it initializes all the members of the structure to default values. Integral variables get initialized to 0, reference types to null etc. This is an inherent property of a struct in .net and the compiler does not want us to break this behavior by allowing us to override the default constructor. This constructor is called by using the new keyword, like this:
struct Widget
{
public string widgetName;
public int widgetId;
public void UpdateWidget()
{
//Some Code
}
}
Widget w = new Widget();
Widget w;
But in the above case, you have to initialize all the members of w explicitly before it (w) can be used.
w.UpdateWidget()
So if you write the above line of code immediately after the Widget declaration, the compiler will throw an error saying:
To get the code to compile, you have to assign values to all the members first.
Widget w;
//Assign values to all the members
w.widgetName = "search widget";
w.widgetId = "66";
//Use the instance
w.UpdateWidget();
This complete assignment rule also applies if you add a parameterized constructor for a struct. Look at the code below.
struct Widget
{
public string widgetName;
public int widgetId;
public Widget(string name)
{
widgetName = name;
}
}
Field ‘StructDemo.Widget.widgetId’ must be fully assigned before control leaves the constructor.
The reason and solution is the same as before.
The default value of a class is null. Since structs are reference types, its default value is the value obtained by setting all its value type members to its default values and reference type members to null. The inability to override the default constructor for a struct guarantees this default state.
![]()
Note that in a class, if you declare a parameterized constructor, it is mandatory that you override the default (parameterless) constructor. In a struct however this restriction is obviously not valid because of the above reasons.
Unlike a class, you cannot initialize instance fields members directly as shown below. You have to rely on a constructor or some other form of explicit assignment to initialize variables to the values you want.
struct Widget
{
public string widgetName = "download widget";
//Compilation error: ‘Widget.widgetName’:
//cannot have instance field initializers
//in structs
}
The keyword this has different meanings when used in a class and a struct. In a class, this is treated as a value. That is, this can be used for assignment (like newVar = this) but cannot be assigned to (like this = newVar). In a struct, however, this is treated as a variable. In an instance constructor, this corresponds to an out parameter whose type is the struct. This is why you get an error if you don’t assign values to all the members in a struct before leaving the constructor. This rule is a property of a regular out parameter in C#. You have to assign it before leaving the method. For a structure, ‘it’ is the entire structure. In a instance method however it is treated as a ref parameter which means that it is possible to assign a whole new struct to the instance that called the method. In short, the code below is valid for a struct.
struct Widget
{
public string widgetName;
public int widgetId;
public Widget(string name, int id)
{
widgetName = name;
widgetId = id;
}
public void SomeMethod()
{
this = new Widget(); //This is valid for structs
}
}
Widget w = new Widget("Search Widget", 66);
MessageBox.Show(w.widgetName); //Displays "Search Widget"
MessageBox.Show(w.widgetId.ToString()); //Displays "66"
m.SomeMethod();
MessageBox.Show(w.widgetName); //Displays "" (was assigned null)
MessageBox.Show(w.widgetId.ToString()); //Displays "0"
As you can see the method replaced its caller with a whole new instance!
So when would you want to use structs? One is obviously if you don’t need the all the features provided by a class such as inheritance. Structs should be used for light weight objects. The guideline is that if the size of a class is around 16 bytes it might be better to make it a struct. Also consider the fact that if you are creating an array of a class, memory has to be allocated on the heap for the actual object in addition to the memory used for the reference on the stack. And this has to be done as many times as the size of the array.
For example, in the following case, a struct would be more efficient.
(struct/class) Point
{
int x;
int y;
}
So there you have it, the lesser known facts about structs. Watch out for more articles in the "What you did not know about…" series.
Code safely,
Alex
I stand corrected. I wonder why I wrote that. Thanks for the heads up. I have crossed out that paragraph.
"Note that in a class, if you declare a parameterized constructor, it is mandatory that you override the default (parameterless) constructor. In a struct however this restriction is obviously not valid because of the above reasons."
Don't think so… Thanks, helpful article.