CodingNeed.

2 · Model and validate · 25 MIN

Records, nullable values and validation

A value model should make invalid states difficult to create.

A record supplies value-oriented equality, but its constructor still needs rules appropriate to the domain. This record validates a category and a nonnegative amount before exposing get-only properties. Nullable reference annotations help the compiler highlight potential null use; they do not prevent invalid values arriving from JSON or a database. Runtime validation remains necessary at external boundaries. Records are shallowly immutable, so mutable child collections need defensive copies when ownership should be isolated.

Enforce invariants when a domain value is constructed.

Read the example

using System;
var first = new Expense("food", 5);
Console.WriteLine(first == new Expense("food",5));
Console.WriteLine(first.Category);
public sealed record Expense {
  public string Category { get; }
  public int Amount { get; }
  public Expense(string category, int amount) {
    if (string.IsNullOrWhiteSpace(category) || amount < 0) throw new ArgumentException("Invalid expense");
    Category = category; Amount = amount;
  }
}
Check the expected output
True
food

Your challenge

Add an immutable report record and validate its category list by copying incoming values.

Solution cost: O(1) scalar construction; defensive copying costs O(n). time · Account for collection storage separately from the returned result. space

Common trap

Nullable annotations document intent but do not validate deserialized data.

Study the project implementation
using System;
var first = new Expense("food", 5);
Console.WriteLine(first == new Expense("food",5));
Console.WriteLine(first.Category);
public sealed record Expense {
  public string Category { get; }
  public int Amount { get; }
  public Expense(string category, int amount) {
    if (string.IsNullOrWhiteSpace(category) || amount < 0) throw new ArgumentException("Invalid expense");
    Category = category; Amount = amount;
  }
}

Further reading: Official documentation

Next lesson: TryParse and expected failures

Essential cookies keep your account signed in. Optional analytics is not configured on this site. Your choice does not affect access to lessons.

Read the Privacy Policy. You can change this choice in the footer.