Deep C# - Structs & Classes
Written by Mike James   
Monday, 08 November 2021
Article Index
Deep C# - Structs & Classes
Simple Types

Simple Types

The simple data types, int, char, etc are clearly value types, but conceptually at least they are also examples of structs. Most of the time you can ignore this fact and just treat them as simple numbers or characters, but they do have methods. For example, int is just an alias for the System.Int32 struct which inherits from object and so it has a ToString method:

int a;
string b = a.ToString();

Each simple type also has methods of its own and even static methods. For example:

int I = int.MaxValue;

Of course, you can’t inherit from a simple type and they have other special features such there being literals of the same type, e.g. 10, 233.34 and so on.

Simple types are structs in spirit only as the compiler takes care to make sure that they are implemented in an efficient manner. Notice that, as with a struct, you can opt to create a simple type using the new keyword. This doesn’t have any effect other than to call the type’s default constructor which results in it being initialized to its default value. So, for example:

int I;
int j;
I = j;

results in a compiler error because j isn’t defined. However:

int I;
int j = new int();
I = j;

works perfectly because j is initialized to 0 by its constructor.

Value or Reference - Decide Early, Don't Change

You should by now understand the difference between a value and a reference type, but when do you use one in preference to another? In most cases this question is simply about using a class or a struct. The answer is nearly always that you should prefer a value type when the purpose is to store data and a reference type when some behavior has to be implemented. Whichever you choose, you need to be aware of the potential for trouble that any attempt at changing a value type to a reference type can produce. For example, suppose we initially design a program using a struct:

public struct MyStruct
  public int x;

We might very well use a method to do some computation involving a private instance of this struct:

private MyStruct MyData = new MyStruct();
public MyStruct doSum()
  return MyData;

In this example no computation is performed - the struct is simply returned. Now if some other part of your program uses this method it might well go on and perform further manipulations on the returned value:

MyStruct a = doSum();
a.x = 10;

In this case everything works as you would expect. The struct is treated using value semantics and the doSum returns a complete copy of the struct to create a completely separate entity in a. This means that storing 10 in the x field doesn’t alter the value stored in MyData.

Now consider the seemingly small change from a struct to a class:

public class MyClass
  public int x;

The change to the private variable and the method are easy enough:

private MyClass MyData = new MyClass();
public MyClass doSum()
  return MyData;

However, if the client program performs the same manipulation:

MyClass a = doSum();
a.x = 10;

the result is very different. Now the object passed as the result is treated as a reference type and subject to reference semantics. This means that doSum passes back a reference to the, supposedly protected, Mydata object. Now when we store 10 in the x field, it is the field in the Mydata object which is changed.

Clearly changing from a value type to a reference type and vice versa is a potentially deep structural change to a program because it changes value semantics into reference semantics.

In Chapter But Not In This Extract

  • Alternative to Structs I – Tuple
  • Alternative to Structs II – Record



Structs are value types, but classes are reference types and never the twain shall meet. Well at least you should keep them well apart in your mind because they behave differently and they are for very different purposes. C#’s structs are more sophisticated than the same idea implemented in other languages and, partly to make up for this, we have two alternatives – the tuple and the record. Both are useful, but it is possible to become excessively addicted to the tuple as a way of temporarily packaging data into a single entity that can be passed around.


Deep C#

 Buy Now From Amazon


 Chapter List

  1. Why C#?

    I Strong Typing & Type Safety
  2. Strong Typing
    Why Strong Typing
  3. Value & Reference
  4.    Extract Value And Reference
  5. Structs & Classes
    Structs & Classes 
  6. Inheritance
  7. Interfaces & Multiple Inheritance
    Extract Interface
  8. Controlling Inheritance
    II Casting & Generics
  9. Casting - The Escape From Strong Typing
    Extract Casting I ***NEW!
  10. Generics
  11. Advanced Generics
  12. Anonymous & Dynamic
    III Functions
  13. Delegates
  14. Multicast Delegates
  15. Anonymous Methods, Lambdas & Closures
    IV Async
  16. Threading, Tasks & Locking
  17. The Invoke Pattern
  18. Async Await
  19. The Parallel For
    V Data - LINQ, XML & Regular Expressions
  20. The LINQ Principle
  21. XML
  22. LINQ To XML
  23. Regular Expressions
    VI Unsafe & Interop
  24. Interop
  25. COM
  26. Custom Attributes
  27. Bit Manipulation
  28. Advanced Structs
  29. Pointers 

Extra Material



To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on Twitter, Facebook or Linkedin.


TypeScript 5.5 Adds ECMAScript Set Support

TypeScript 5.5 is now available as a release candidate. This version adds support for the proposed ECMAScript Set methods, as well as inferred type predicates and the ability to narrow expressions for [ ... ]

Deno Adds Support For Private npm Registries

Deno 1.44 has been released with support for private npm registries and for gRPC connections.

More News

C book



or email your comment to:


Last Updated ( Monday, 08 November 2021 )