C-SHARP - 7.4 Defensive programming

Defensive programming starts from a simple principle: never blindly trust the data that enters a method. Whether that data comes from a user, an API call, a file, or another part of the code, it can be null, empty, out of range, or malformed. A well-written method checks its assumptions right away and reacts clearly when they aren't met.

The first instinct is explicit parameter validation at the start of a method. A check like if (input == null) throw new ArgumentNullException(nameof(input)); documents the expectation and immediately flags incorrect usage, instead of letting the code crash three levels further down with an obscure message. For strings, you'll typically test string.IsNullOrWhiteSpace; for collections, you'll check whether elements are present; for numbers, you'll enforce the expected bounds.

Exception handling is the other pillar. Rather than catching a blanket catch (Exception) that hides real problems, you catch specific exceptions (FormatException, FileNotFoundException, InvalidOperationException) with a reaction suited to each one. When the situation is unrecoverable at the current level, you let the exception propagate so it can be handled higher up, where the context allows for a relevant decision.

This approach isn't a security obsession: it's an investment of a few lines that saves hours of debugging. Defensive code is longer but far more predictable. Combined with the debugging tools covered earlier and the removal of side effects, it forms the trio behind professional C# code.