Introduction: Why Errors Are Normal
Every developer's journey begins with errors. C# (.NET) is a powerful and strongly typed language that forgives less than dynamic languages, but in return gives reliability and performance. In this article, we'll break down the 4 most common pitfalls that beginners stumble on and show how to avoid them. This article will be useful both for those just starting to learn C# and for those who want to refresh their knowledge.
1. Ignoring null and NullReferenceException
The most popular error in C# is NullReferenceException. It occurs when you try to access a member of an object that is null.
Example of the Problem
string text = null;int length = text.Length; // Error! NullReferenceExceptionBeginners often forget to check values returned from methods, or rely on the assumption that an object definitely exists.
How to Do It Correctly
- Always check objects for
nullbefore using them. - Use the
?.(null-conditional) and??(null-coalescing) operators.
string text = GetText(); // may return nullint? length = text?.Length; // if text == null, length will be nullint safeLength = text?.Length ?? 0; // if null, then 0Console.WriteLine(safeLength);Also in C# 8.0+, nullable reference types appeared, which are enabled via #nullable enable. They force you to explicitly specify whether a variable can be null, and warn about potential problems at compile time.
2. Incorrect Use of var and Loss of Readability
The var keyword allows the compiler to determine the type of a variable itself. This is convenient, but beginners often overuse it, making the code unreadable.
Example of Bad Code
var data = GetData();var result = Process(data);var output = Transform(result); // What types? Unclear.In a month, you (or your colleague) won't be able to quickly understand what type data is without looking at the method definition.
When to Use var
- When the type is obvious from the right-hand side (e.g.,
var list = new List<int>();) - When working with anonymous types and LINQ queries.
// Good: type is obviousvar numbers = new List<int> { 1, 2, 3 };
// Good: anonymous typevar person = new { Name = "John", Age = 30 };
// Bad: type is unclearvar config = LoadConfiguration(); // Better: Configuration config = LoadConfiguration();Golden rule: use var only when it improves readability, not reduces it.
3. Swallowing Exceptions and Empty catch Blocks
Many beginners, when encountering exceptions, write an empty catch or simply output a message without analyzing the error. This makes the program unstable and complicates debugging.
Example of an Anti-pattern
try{ int.Parse("not a number");}catch (Exception){ // Do nothing — the error is "swallowed"}The application will continue running, but in an incorrect state. The user won't know about the problem, and data may be corrupted.
How to Handle Exceptions Correctly
- Don't catch general
Exceptionunless you plan to handle all types of errors. - Catch only those exceptions that you can handle (e.g.,
FormatException,FileNotFoundException). - Use
finallyto release resources (files, connections). - Log errors.
try{ int number = int.Parse(userInput);}catch (FormatException ex){ // Log and inform the user