10 Lesser-Known C# Operators That Will Surprise You (With Examples)

When most developers think of C# operators, they picture the basics: +, -, *, /, =, ==. But beyond the everyday syntax, C# has a rich set of specialized operators that can simplify your code, reduce bugs, and even improve performance in certain scenarios.

Many of these operators are underutilized because they don’t get much attention in beginner tutorials. In this post, we’ll take a deep dive into 10 lesser-known C# operators, explain how they work, why they’re useful, and provide clear “old way vs new way” code comparisons so you can see exactly why these operators exist.

Note that there’s a “Sidebar” section toward the end with more information about what the question mark operators are used for.

1. Null-Coalescing Operator (??)

The null-coalescing operator returns the left-hand operand if it isn’t null. Otherwise, it returns the right-hand operand.

Old Way

The old way required an “if” check for null

New Way

Notice that the “if” check for null is no longer required

✅ Cleaner, less typing, and avoids repetitive null checks.

2. Null-Coalescing Assignment (??=)

Introduced in C# 8.0, this operator assigns a value only if the variable is currently null.

Old Way

Another unnecessary check for null

New Way

More concise syntax for assignment when null

✅ Compact, perfect for lazy initialization.

3. Null-Conditional Operator (?.)

The null-conditional operator (sometimes called the Elvis operator) safely calls members without throwing a NullReferenceException.

Old Way

Annoying nested checks for null

New Way

More concise syntax

✅ One operator replaces multiple nested checks.

4. Pattern Matching with is and when

Modern C# extends the is operator to support pattern matching.

Old Way

A cast was required previously

New Way

No explicit casting required

✅ Combines type check + safe cast + condition in one statement.

5. nameof Operator

The nameof operator returns the name of a variable, property, or type as a string—safer than hardcoding.

Old Way

Using hard coded strings is not ideal- programs change over time

New Way

Now using the “nameof” operator

✅ Refactor-safe: if you rename FirstName, the compiler updates it automatically.

6. checked and unchecked

These operators give you explicit control over numeric overflow.

Old Way (Silent Bug)

Remember that ints have a fixed number of bits and can max out in value. They overflow when you exceed that, very bad…

New Way

Now you can at least be notified if overflow occurs

✅ Makes overflow behavior explicit.

7. stackalloc

The stackalloc operator allocates memory on the stack instead of the heap.

Old Way (Heap Allocation)

Array is allocated on the heap by default

New Way (Stack Allocation)

Now the array is placed on the stack

✅ Faster, avoids garbage collection.

⚠️ Use only for small buffers due to limited stack size.

8. The -> Operator (Unsafe Code)

The -> operator is shorthand for accessing members via a pointer.

Old Way

Dereferencing a pointer to access and manipulate the pointed to object

New Way

Arrow syntax to access data

✅ Cleaner syntax for unsafe pointer operations.

9. Ternary Conditional Operator (?:)

Inline conditional expressions.

Old Way

Using a conditional “if/else” statement

New Way

Concise syntax with the ternary operator

✅ Perfect for compact logic.

10. default Literal

Introduced in C# 7.1, this operator produces the default value of a type.

Old Way

Note that the variable type is passed to default

New Way

The type of the value can be inferred from the variable type on the left hand side

✅ Cleaner, especially in generics.

Sidebar: What Does ? After a Type Mean in C#?

You’ll notice some examples use int? or string?. The ? means nullable type:

  • For value types (e.g., int?, bool?) → allows null (normally value types cannot be null).

  • For reference types (e.g., string?) → in modern C# with nullable annotations, the ? means “this reference may legally be null.”

Examples:

Adding the question mark to the variable type denotes that it is nullable, or able to accept null as a value

Why would you want that?

Here are some common use cases:

1. Optional data in databases or APIs

When mapping to a database column that allows nulls, or consuming an API where a field may be missing, you need a way to represent “no value.”

int? middleNameId = null; // optional foreign key

2. Uninitialized state

Sometimes you can’t assign a value until later. Instead of using a “magic number” like -1, nullable types let you explicitly express “not yet set.”

int? score = null; // hasn't been calculated yet

3. Distinguishing between “zero” and “nothing”

In some domains, 0 has meaning (“paid nothing”), while null means the data isn’t known yet.

decimal? amountPaid = null; // payment not reported yet

4. User input and forms

When users can leave fields blank, string? lets you clearly model optional inputs.

string? phoneNumber = null; // optional form field

5. Expressive domain models

By marking properties as nullable, your code communicates intent clearly—no need for hidden assumptions or special comments.

public class Customer
{
    public string Name { get; set; } = string.Empty;
    public string? MiddleName { get; set; } // explicitly optional
}

Summary

  • Use int? when a number might not exist yet.

  • Use string? when text might be missing or optional.

  • Nullable types reduce reliance on placeholder values and make your code clearer, safer, and closer to the real-world domain you’re modeling.

Conclusion

We’ve explored 10 C# operators that don’t always get the spotlight but can make a huge difference in how you write code:

  • ??, ??=, and ?. → safer, cleaner null handling.

  • nameof, checked, and default → fewer bugs and easier refactoring.

  • stackalloc and -> → advanced performance features.

  • ?: and pattern matching → concise, expressive logic.

Many of these operators shine brightest when paired with nullable types (T?). By allowing your code to explicitly represent “no value,” you avoid placeholder hacks like -1 or empty strings, and instead model your problem domain more truthfully. Operators like ?? and ?. then become natural tools for working with those nullable values safely and clearly.

The result? Code that’s not just functional, but also:

  • Expressive → communicates intent directly in the type system.

  • Resilient → avoids common pitfalls like NullReferenceException.

  • Efficient → in both writing and execution.

By mastering these lesser-known operators, you’ll level up from writing code that merely works to writing code that’s idiomatic, safe, and built to last.

Next
Next

C# Records Explained: Why and How to Use Them