Difference between Struct and Class
Struct | Class |
---|---|
Struct are value types. | Classes are of reference types. |
Struct are stored on the stack. | Classes are stored on the heap. |
Being a value type they hold their value in memory when they are declared. | In case of classes, the type holds a reference to an object memory. |
Value types are destroyed immediately after the scope is lost. | In reference type only the variable gets destroyed after the scope id lost. Object is destroyed later by Garbage Collector. |
When you copy struct into another struct, a new copy of that struct gets created modified of one struct won’t affect the value of the other struct. | When you copy a class into another class, it only copies the reference variable. |
Structs can not have destructors. | Classes can have destructors |
Structs can not have explicit parameterless constructors | Classes can have explicit parameterless constructors |
1 Per thread | 1 per application |
Can’t have null values | Can have null values |
Comparison of Struct and Class
Struct | Class | ||
---|---|---|---|
Type | Value-type | Reference-type | |
Where | On stack / Inline in containing type | On Heap | |
Deallocation | Stack unwinds / containing type gets deallocated | Garbage Collected | |
Arrays | Inline, elements are the actual instances of the value type | Out of line, elements are just references to instances of the reference type residing on the heap | |
Al-Del Cost | Cheap allocation-deallocation | Expensive allocation-deallocation | |
Memory usage | Boxed when cast to a reference type or one of the interfaces they implement, Unboxed when cast back to value type (Negative impact because boxes are objects that are allocated on the heap and are garbage-collected) | No boxing-unboxing | |
Assignments | Copy entire data | Copy the reference | |
Change to an instance | Does not affect any of its copies | Affect all references pointing to the instance | |
Mutability | Should be immutable | Mutable | |
Population | In some situations | Majority of types in a framework should be classes | |
Lifetime | Short-lived | Long-lived | |
Destructor | Cannot have | Can have | |
Inheritance | Only from an interface | Full support | |
Polymorphism | No | Yes | |
Sealed | Yes | When have sealed keyword | |
Constructor | Can not have explicit parameterless constructors | Any constructor | |
Null-assignments | When marked with nullable question mark | Yes | ) |
Abstract | No | When have abstract keyword | |
Member Access Modifiers | public, private, internal | public, protected, internal, protected internal, private protected |
Application Memory in struct and classes
Image reference : Stackoverflow
Choosing between class and struct
As a rule of thumb, the majority of types in a framework should be classes. There are, however, some situations in which the characteristics of a value type make it more appropriate to use structs.
✔️ CONSIDER defining a struct instead of a class if instances of the type are small and commonly short-lived or are commonly embedded in other objects.
❌ AVOID defining a struct unless the type has all of the following characteristics:
- It logically represents a single value, similar to primitive types (
int
,double
, etc.). - It has an instance size under 16 bytes.
- It is immutable.
- It will not have to be boxed frequently.
In all other cases, you should define your types as classes.
reference : https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/choosing-between-class-and-struct