Struct or Class in C#: The Eternal Debate of Beginners and Pros
\n\nHave you ever wondered why C# has two very similar ways to create your own data type — class and struct? And why on Stack Overflow the question “When should I use a struct rather than a class in C#?” gathers thousands of views and hundreds of answers? The thing is, behind the apparent simplicity lies a deep nuance that can either speed up your program or turn it into a breeding ground for bugs.
In this article, we’ll break down how struct differs from class, when you should use struct, and when it’s better to forget it exists. No fancy jargon, just real-life examples and practical advice. Let’s go!
\n\nThe Main Difference: Stack or Heap?
\n\nThe most important point to understand is value types and reference types.
\n\n- \n
- Class — a reference type. The object is stored in the managed heap, and the variable only holds a reference (address) to that object. \n
- Struct — a value type. The variable stores the data itself directly on the stack or inside another object. \n
Sounds abstract? Let’s use an example. Imagine data is a book. A class is the book’s title and the shelf number where it sits in the library. A struct is the book itself, which you carry in your pocket. When you pass a class to a method, you pass the shelf number. When you pass a struct, you hand over a copy of the book.
\n\nCode Example: class vs struct
\n\npublic class PointClass\n{\n public int X { get; set; }\n public int Y { get; set; }\n\n public PointClass(int x, int y)\n {\n X = x;\n Y = y;\n }\n}\n\npublic struct PointStruct\n{\n public int X { get; set; }\n public int Y { get; set; }\n\n public PointStruct(int x, int y)\n {\n X = x;\n Y = y;\n }\n}\n\n// Usage\nvar pointClass = new PointClass(10, 20);\nvar pointStruct = new PointStruct(10, 20);\n\n// Passing to a method\nvoid ModifyPointClass(PointClass p) { p.X = 100; }\nvoid ModifyPointStruct(PointStruct p) { p.X = 100; }\n\nModifyPointClass(pointClass); // pointClass.X becomes 100\nModifyPointStruct(pointStruct); // pointStruct.X remains 10 — a copy!\n\n\nSee? Struct is copied when passed. This is the key difference that determines when to use it.
\n\nWhen Struct is Your Friend: 3 Rock-Solid Cases
\n\nMicrosoft recommends using struct if your data type meets ALL of the following conditions:
1. Data is Small and Simple
\nStruct is ideal for small data sets (recommended no more than 16-24 bytes). For example, a point, color, vector, complex number, or coordinates.
\n\npublic struct RgbColor\n{\n public byte R { get; }\n public byte G { get; }\n public byte B { get; }\n\n public RgbColor(byte r, byte g, byte b)\n {\n R = r;\n G = g;\n B = b;\n }\n}\n\n\nWhy? Because small structs copy quickly, and storing them on the stack reduces the load on the garbage collector (GC).
\n\n2. Objects are Short-Lived and Immutable
\nIf your data consists of immutable values, struct is an excellent choice. For example, map coordinates: you don’t change a point, you create a new one.
\n\npublic struct GeoLocation\n{\n public double Latitude { get; }\n public double Longitude { get; }\n\n public GeoLocation(double lat, double lon)\n {\n Latitude = lat;\n Longitude = lon;\n }\n\n public GeoLocation MoveNorth(double meters)\n {\n // Return a new instance, don't modify the old one\n return new GeoLocation(Latitude + meters / 111111.0, Longitude);\n }\n}\n\n\n