C# tutorials > Core C# Fundamentals > Object-Oriented Programming (OOP) > What is a class and a struct in C#, and when to use each?
What is a class and a struct in C#, and when to use each?
In C#, both classes and structs are used to define custom data types. However, they have fundamental differences that dictate when to use one over the other. Understanding these differences is crucial for writing efficient and maintainable code.
Definition and Basic Syntax
Both classes and structs allow you to define properties and methods. The primary difference lies in how they are treated in memory.
// Class Definition
public class MyClass
{
public int MyProperty { get; set; }
public void MyMethod() { }
}
// Struct Definition
public struct MyStruct
{
public int MyProperty { get; set; }
public void MyMethod() { }
}
Key Differences: Value vs. Reference Types
Classes are reference types: When you create an instance of a class, you're creating an object on the heap. The variable that holds the object actually stores a reference to the memory location on the heap. Assigning a class object to another variable copies the reference, so both variables point to the same object in memory. Changes to one variable affect the other. Structs are value types: When you create an instance of a struct, it's stored directly within the variable itself (typically on the stack). Assigning a struct to another variable copies the entire struct, creating a completely independent copy. Changes to one variable do not affect the other.
Memory Footprint
Structs generally have a smaller memory footprint than classes, especially for simple data structures, because they avoid the overhead of the heap allocation. However, copying large structs frequently can be less efficient than working with references to class objects.
Default Constructor
Classes: If you don't define a constructor, the compiler provides a default parameterless constructor. You can also define multiple constructors. Structs: Prior to C# 10, structs could not have explicit parameterless constructors. C# 10 and later allows you to define a parameterless constructor, but it must initialize all fields within the struct. Otherwise, the struct will be considered uninitialized.
Inheritance
Classes: Support inheritance. A class can inherit from another class (single inheritance) and implement multiple interfaces. Structs: Do not support inheritance from another class or struct. However, a struct can implement interfaces.
When to use them
Use structs when: Use classes when:
Concepts Behind the Snippet
The fundamental concepts illustrated in the initial code snippets are:
Real-Life Use Case Section
Point (Struct): Represents a coordinate in 2D space. It's small, logically represents a single value, and is often copied when passed as arguments to functions. Customer (Class): Represents a customer in a system. It has properties like name, address, and a list of orders. It's more complex, likely has a longer lifespan, and benefits from reference-type semantics.
// Example of using a struct for a Point
public struct Point
{
public int X { get; set; }
public int Y { get; set; }
public Point(int x, int y)
{
X = x;
Y = y;
}
}
// Example of using a class for a Customer
public class Customer
{
public string Name { get; set; }
public string Address { get; set; }
public List<Order> Orders { get; set; }
}
Best Practices
Interview Tip
When asked about the difference between classes and structs, emphasize the value type vs. reference type distinction. Also, mention the implications for memory management (stack vs. heap) and the performance considerations of copying structs versus passing references to objects. Be prepared to discuss scenarios where you would choose one over the other, providing concrete examples.
Pros and Cons
Classes: Pros:
Cons:
- Heap allocation overhead.
- Potential for memory leaks if not managed properly (though garbage collection mitigates this).
Structs:
Pros:
- Lightweight and efficient for small data structures.
- Value-type semantics for independent copies.
- Stack allocation for faster access.
Cons:
- No inheritance.
- Copying large structs can be inefficient.
- Potential for boxing/unboxing overhead when used with interfaces.
Alternatives
Alternatives to consider when choosing between classes and structs include:
FAQ
-
When should I use a `readonly struct`?
Use `readonly struct` when you have a struct that should be immutable. This provides compile-time guarantees that the struct cannot be modified after creation, and can improve performance because the compiler can optimize the code more effectively.
-
What is boxing and unboxing, and why is it relevant to structs?
Boxing is the process of converting a value type (like a struct) to a reference type (like `object`). Unboxing is the reverse process. Boxing occurs when you pass a struct to a method that expects an `object` or when you store a struct in a collection of type `object`. This can introduce performance overhead because it involves allocating memory on the heap and copying the struct's data. Try to minimize boxing/unboxing by using generics where possible.
-
Are structs always faster than classes?
No, structs are not always faster than classes. While structs avoid heap allocation overhead, copying large structs can be slower than passing references to class objects. The best choice depends on the size and complexity of the data structure and how frequently it is copied.