How to Use the nameof Operator for Safer Refactoring in C#

Refactoring code can be risky, especially when dealing with hardcoded string literals representing variable, property, or method names.

One small change in a name could lead to runtime errors that are difficult to track down. Fortunately, C# provides the nameof operator to make refactoring safer and more maintainable.

What is the nameof Operator?

The nameof operator in C# returns the string representation of a variable, method, or class name at compile time. This makes your code more resilient to name changes since the compiler will catch errors if a referenced identifier is renamed or removed.

Basic Usage

Instead of using hardcoded strings, use nameof to reference identifiers dynamically:

class Person
{
    public string FirstName { get; set; }
}

void PrintPropertyName()
{
    Console.WriteLine(nameof(Person.FirstName)); // Output: "FirstName"
}

If FirstName is renamed, the compiler will flag the change, helping prevent runtime errors.

Benefits of Using nameof

  1. Safer Refactoring: When renaming identifiers, the compiler ensures nameof references update automatically.
  2. Improved Readability: Code intent is clearer, avoiding magic strings.
  3. Fewer Runtime Errors: No risk of typos or mismatches in string literals.

Practical Examples

Logging

Using nameof ensures that logs remain accurate even after refactoring:

void LogError(string message, string propertyName)
{
    Console.WriteLine($"Error in {propertyName}: {message}");
}

LogError("Invalid value", nameof(Person.FirstName));

Argument Validation

Validating method parameters without hardcoded strings:

void SetAge(int age)
{
    if (age < 0)
        throw new ArgumentException("Age cannot be negative", nameof(age));
}

Dependency Injection

When working with DI frameworks, nameof prevents issues with binding:

services.AddSingleton<ILogger, Logger>(provider =>
    new Logger(nameof(Logger)));

Conclusion

The nameof operator is a simple yet powerful feature in C# that improves code maintainability and prevents common errors during refactoring. By replacing hardcoded strings with nameof, you can make your applications more robust and future-proof.

0
28

Related

Closing a SqlDataReader correctly prevents memory leaks, connection issues, and unclosed resources. Here’s the best way to do it.

Use 'using' to Auto-Close

Using using statements ensures SqlDataReader and SqlConnection are closed even if an exception occurs.

Example

using (SqlConnection conn = new SqlConnection(connectionString))
{
    conn.Open();
    using (SqlCommand cmd = new SqlCommand("SELECT * FROM Users", conn))
    using (SqlDataReader reader = cmd.ExecuteReader())
    {
        while (reader.Read())
        {
            Console.WriteLine(reader["Username"]);
        }
    } // ✅ Auto-closes reader here
} // ✅ Auto-closes connection here

This approach auto-closes resources when done and it is cleaner and less error-prone than manual closing.

⚡ Alternative: Manually Close in finally Block

If you need explicit control, you can manually close it inside a finally block.

SqlDataReader? reader = null;
try
{
    using SqlConnection conn = new SqlConnection(connectionString);
    conn.Open();
    using SqlCommand cmd = new SqlCommand("SELECT * FROM Users", conn);
    reader = cmd.ExecuteReader();

    while (reader.Read())
    {
        Console.WriteLine(reader["Username"]);
    }
}
finally
{
    reader?.Close();  // ✅ Closes reader if it was opened
}

This is slightly more error prone if you forget to add a finally block. But might make sense when you need to handle the reader separately from the command or connection.

0
154

In C#, you can format an integer with commas (thousands separator) using ToString with a format specifier.

int number = 1234567;
string formattedNumber = number.ToString("N0"); // "1,234,567"
Console.WriteLine(formattedNumber);

Explanation:

"N0": The "N" format specifier stands for Number, and "0" means no decimal places. The output depends on the culture settings, so in regions where , is the decimal separator, you might get 1.234.567.

Alternative:

You can also specify culture explicitly if you need a specific format:

using System.Globalization;

int number = 1234567;
string formattedNumber = number.ToString("N0", CultureInfo.InvariantCulture);
Console.WriteLine(formattedNumber); // "1,234,567"
3
391

Raw string literals in C# provide a flexible way to work with multiline strings, with some interesting rules around how quotes work.

The key insight is that you can use any number of double quotes (three or more) to delimit your string, as long as the opening and closing sequences have the same number of quotes.

The Basic Rules

  1. You must use at least three double quotes (""") to start and end a raw string literal
  2. The opening and closing quotes must have the same count
  3. The closing quotes must be on their own line for proper indentation
  4. If your string content contains a sequence of double quotes, you need to use more quotes in your delimiter than the longest sequence in your content

Examples with Different Quote Counts

// Three quotes - most common usage
string basic = """
    This is a basic
    multiline string
    """;

// Four quotes - when your content has three quotes
string withThreeQuotes = """"
    Here's some text with """quoted""" content
    """";

// Five quotes - when your content has four quotes
string withFourQuotes = """""
    Here's text with """"nested"""" quotes
    """"";

// Six quotes - for even more complex scenarios
string withFiveQuotes = """"""
    Look at these """""nested""""" quotes!
    """""";

The N+1 Rule

The general rule is that if your string content contains N consecutive double quotes, you need to wrap the entire string with at least N+1 quotes. This ensures the compiler can properly distinguish between your content and the string's delimiters.

// Example demonstrating the N+1 rule
string example1 = """
    No quotes inside
    """; // 3 quotes is fine

string example2 = """"
    Contains """three quotes"""
    """"; // Needs 4 quotes (3+1)

string example3 = """""
    Has """"four quotes""""
    """""; // Needs 5 quotes (4+1)

Practical Tips

  • Start with three quotes (""") as your default
  • Only increase the quote count when you actually need to embed quote sequences in your content
  • The closing quotes must be on their own line and should line up with the indentation you want
  • Any whitespace to the left of the closing quotes defines the baseline indentation
// Indentation example
string properlyIndented = """
    {
        "property": "value",
        "nested": {
            "deeper": "content"
        }
    }
    """; // This line's position determines the indentation

This flexibility with quote counts makes raw string literals extremely versatile, especially when dealing with content that itself contains quotes, like JSON, XML, or other structured text formats.

1
74