Introduction
Structs in C# are value types that can encapsulate data and related functionality. They are similar to classes but are more lightweight and are typically used for small data structures. Structs are stored on the stack, which makes them more efficient in terms of memory allocation compared to classes that are reference types and stored on the heap.
Defining a Struct
You define a struct using the struct
keyword, followed by the struct name and the body containing fields, properties, methods, and constructors.
Syntax
public struct StructName
{
// Fields
public dataType fieldName;
// Properties
public dataType PropertyName { get; set; }
// Constructor
public StructName(parameters)
{
// Initialization code
}
// Methods
public void MethodName()
{
// Method code
}
}
Example
public struct Point
{
// Fields
public int X;
public int Y;
// Constructor
public Point(int x, int y)
{
X = x;
Y = y;
}
// Method
public void Display()
{
Console.WriteLine($"Point: ({X}, {Y})");
}
}
Using Structs
You can create and use structs similar to how you use classes, but with some key differences due to their value type nature.
Example
using System;
namespace StructExample
{
public struct Point
{
public int X;
public int Y;
public Point(int x, int y)
{
X = x;
Y = y;
}
public void Display()
{
Console.WriteLine($"Point: ({X}, {Y})");
}
}
class Program
{
static void Main(string[] args)
{
Point p1 = new Point(10, 20);
p1.Display(); // Outputs: Point: (10, 20)
Point p2;
p2.X = 30;
p2.Y = 40;
p2.Display(); // Outputs: Point: (30, 40)
}
}
}
Output
Point: (10, 20)
Point: (30, 40)
Key Differences Between Structs and Classes
- Value Type vs Reference Type: Structs are value types, meaning they are stored on the stack and copied when passed around. Classes are reference types, meaning they are stored on the heap and references to them are passed around.
- Default Constructor: Structs cannot have a parameterless constructor. They always have an implicit default constructor that initializes fields to their default values.
- Inheritance: Structs cannot inherit from other structs or classes, and they cannot be the base of another struct or class. However, they can implement interfaces.
- Memory Allocation: Structs are allocated on the stack (or inline in arrays or other containing types), which can lead to better performance in certain scenarios due to reduced garbage collection overhead.
Example: Struct with Properties and Methods
Example
using System;
namespace StructWithPropertiesExample
{
public struct Rectangle
{
// Fields
private double length;
private double width;
// Constructor
public Rectangle(double length, double width)
{
this.length = length;
this.width = width;
}
// Properties
public double Length
{
get { return length; }
set { length = value; }
}
public double Width
{
get { return width; }
set { width = value; }
}
// Method
public double GetArea()
{
return length * width;
}
public void Display()
{
Console.WriteLine($"Rectangle: Length = {length}, Width = {width}, Area = {GetArea()}");
}
}
class Program
{
static void Main(string[] args)
{
Rectangle rect = new Rectangle(10.5, 4.5);
rect.Display(); // Outputs: Rectangle: Length = 10.5, Width = 4.5, Area = 47.25
rect.Length = 12;
rect.Width = 5;
rect.Display(); // Outputs: Rectangle: Length = 12, Width = 5, Area = 60
}
}
}
Output
Rectangle: Length = 10.5, Width = 4.5, Area = 47.25
Rectangle: Length = 12, Width = 5, Area = 60
Passing Structs to Methods
When you pass a struct to a method, a copy of the struct is passed, not a reference. This means changes made to the struct inside the method do not affect the original struct.
Example
using System;
namespace StructPassExample
{
public struct Point
{
public int X;
public int Y;
public Point(int x, int y)
{
X = x;
Y = y;
}
public void Display()
{
Console.WriteLine($"Point: ({X}, {Y})");
}
}
class Program
{
static void Main(string[] args)
{
Point p1 = new Point(10, 20);
ModifyPoint(p1);
p1.Display(); // Outputs: Point: (10, 20)
}
static void ModifyPoint(Point p)
{
p.X = 100;
p.Y = 200;
}
}
}
Output
Point: (10, 20)
Structs and Performance
Structs can provide performance benefits due to their value type semantics and stack allocation, but they should be used judiciously. Overuse of large structs can lead to performance issues due to increased copying. As a rule of thumb, use structs for small, simple data structures that are immutable or logically represent a single value.
Conclusion
Structs in C# are a powerful feature for creating lightweight data structures that encapsulate data and related functionality. They are value types and are typically used for small, simple objects. Understanding the differences between structs and classes and knowing when to use each can help you write more efficient and maintainable code.