# Types, Variables and Value vs Reference — C#/.NET

Source: https://www.skillbyai.com/en/dotnet/f-types

> Choose built-in types and predict how value and reference types behave when copied.

## Two kinds of types

Every C# type is a **value type** or a **reference type**. **Value types** (`int`, `long`, `double`, `decimal`, `bool`, `char`, `DateTime`, enums and any `struct`) hold their data directly; assigning one copies the value. **Reference types** (`string`, arrays, `class` instances, `record` classes, delegates) hold a reference to an object on the managed heap; assigning one copies the **reference**, so two variables can point to the same object. Use `decimal` for money (base-10, no binary rounding surprises) and `double` for scientific values. `var` asks the compiler to infer the type; it is still statically typed. `string` is a reference type but **immutable**: methods like `ToUpper()` return new strings. Integer arithmetic wraps on overflow by default; a `checked` block or the `CheckForOverflowUnderflow` project setting throws `OverflowException` instead.

## Copying values versus references

The struct copy is independent; the class copy shares one object.

```cs
var p1 = new PointStruct { X = 1 };
var p2 = p1;          // copies the value
p2.X = 99;
Console.WriteLine(p1.X);   // still 1

var c1 = new PointClass { X = 1 };
var c2 = c1;          // copies the reference
c2.X = 99;
Console.WriteLine(c1.X);   // 99: same object

decimal price = 0.1m + 0.2m;   // exactly 0.3
double approx = 0.1 + 0.2;     // 0.30000000000000004

struct PointStruct { public int X; }
class PointClass { public int X; }
```

## Large mutable structs are a trap

Structs are copied on every assignment and method call. Keep structs small and preferably immutable (`readonly struct`), or you will modify a copy and wonder why the original did not change.

**Quiz:** Which type should you use for currency amounts in C#?

- [ ] float
- [ ] double
- [x] decimal
- [ ] int with implicit rounding

*Answer:* decimal. decimal is a base-10 type designed for financial values, avoiding binary floating-point rounding errors.
