At its core, a variable is just a human-friendly name for a physical memory address. However, C# is Statically Typed, meaning every variable must have a known type. The most critical distinction to master for performance and bug-prevention is the difference between Value Types and Reference Types.
Value types (e.g., int, bool, double, struct) store the actual data directly inside the variable. They live on the **Stack** memory, which is lightning fast but very small.
int a = 10;
int b = a; // A COMPLETE COPY of the data is made.
b = 20; // 'a' remains 10. They are independent.
Reference types (e.g., class, string, array) do NOT store data. They store a "Pointer" (memory address). The actual data lives on the **Heap**, which is massive but slower to access.
var userA = new User { Name = "Sandeep" };
var userB = userA; // Only the ADDRSS is copied!
userB.Name = "Model";
Console.WriteLine(userA.Name); // Prints "Model"! They point to the same memory object.
C# allows you to use the var keyword to let the compiler guess the type. Note: C# is NOT dynamic. Once 'var' is assigned, its type is locked forever.
var name = "Sandeep"; // Compiler knows this is string
// name = 50; // ERROR! Compiler won't let you change type.
Q: "If strings are classes (Reference types), why do they act like Value types when I use the equality operator (==)?"
Architect Answer: "This is 'Operator Overloading.' While strings are technically reference types stored on the heap, Microsoft has overloaded the `==` operator specifically for the string class to perform a 'Value Comparison' (checking if the characters match) instead of a 'Reference Comparison' (checking if both point to the same memory address). This makes the language much more intuitive. For almost every other class, `==` would check if they are the same memory instance."