DEV Community

Cover image for Exploring the Top New Features in C# 12: How They Can Simplify and Enhance Your Code
Leandro Veiga
Leandro Veiga

Posted on

Exploring the Top New Features in C# 12: How They Can Simplify and Enhance Your Code

With every new release, C# continues to evolve, making it easier to write efficient, clean, and maintainable code. C# 12 is packed with exciting new features that simplify complex tasks, reduce boilerplate code, and enhance readability. Whether you're a seasoned C# developer or just diving into the language, these new features will help you write better code with less effort.

In this post, we'll explore some of the most impactful features introduced in C# 12, along with practical examples to show how they can streamline your workflow and boost productivity.


1. Primary Constructors for Non-Record Classes

Primary constructors, previously exclusive to records, are now available for non-record classes in C# 12. This feature allows you to define constructor parameters directly in the class declaration, reducing boilerplate code and improving readability.

Example:

public class Employee(string name, int id)
{
    public string Name { get; } = name;
    public int Id { get; } = id;
}
Enter fullscreen mode Exit fullscreen mode

With primary constructors, there's no need to define a separate constructor or set properties manually, making your classes more concise and easier to read.


2. Collection Expressions

Collection expressions are a new way to initialize collections using concise syntax. They allow you to define collections with a simpler, more intuitive syntax, which is especially useful when working with complex data structures.

Example:

var numbers = [1, 2, 3, 4, 5];
var names = ["Alice", "Bob", "Charlie"];
Enter fullscreen mode Exit fullscreen mode

This feature is not only cleaner but also makes your code more readable, reducing the verbosity associated with traditional collection initializers.


3. Default Lambda Parameter Values

Setting default values for lambda parameters is a long-awaited feature that has finally arrived in C# 12. This allows you to specify default values for parameters in lambda expressions, which is particularly useful for event handling or custom delegates.

Example:

Func<int, int, int> add = (a, b = 5) => a + b;
Console.WriteLine(add(10)); // Output: 15
Enter fullscreen mode Exit fullscreen mode

Default lambda parameters enhance flexibility, letting you create more adaptable lambdas without needing to overload or redefine the expression.


4. Interpolated String Handlers with Custom Logic

C# 12 introduces the ability to create custom interpolated string handlers, enabling you to control the behavior of string interpolation at a granular level. This feature is perfect for logging, formatting, and managing memory in performance-sensitive applications.

Example:

public class CustomLogger
{
    public void Log(string message) => Console.WriteLine(message);
    public void LogInterpolated(string message)
    {
        Log($"[INFO] {message}");
    }
}
Enter fullscreen mode Exit fullscreen mode

With custom interpolated string handlers, you can create efficient and tailored logging or formatting solutions that adapt to specific scenarios.


5. Primary Constructor with Field Keywords

C# 12 brings the ability to declare primary constructor parameters as fields directly. This feature eliminates the need to declare additional properties or fields, which helps reduce boilerplate code.

Example:

public class Point(public int x, public int y);
Enter fullscreen mode Exit fullscreen mode

This feature makes code more compact, as there’s no need to manually create properties or fields for constructor parameters.


6. Inline Collections with Ranges and Slices

Inline collections can now work with ranges and slices in C# 12, making it easier to access specific parts of collections without additional indexing logic. This feature is ideal for cases where you need quick access to a subset of data in arrays or lists.

Example:

var array = [1, 2, 3, 4, 5];
var subArray = array[1..3]; // Output: [2, 3]
Enter fullscreen mode Exit fullscreen mode

This enhancement increases readability and flexibility when working with collections, as you can access ranges directly without extra steps.


7. Enhanced Switch Expressions with Named Variables

Switch expressions have been enhanced with the capability to use named variables, making them more powerful for pattern matching and logical control. This feature allows for more descriptive and maintainable switch statements.

Example:

var result = shape switch
{
    Circle c => $"Circle with radius {c.Radius}",
    Square s => $"Square with side length {s.SideLength}",
    _ => "Unknown shape"
};
Enter fullscreen mode Exit fullscreen mode

Named variables in switch expressions allow for easier access to properties in complex conditional logic, enhancing the expressiveness of your code.


8. File-Scoped Types

File-scoped types, now available in C# 12, allow you to define types scoped to a single file, providing better encapsulation. This feature is useful when you want to prevent certain types from being accessible across multiple files, promoting better organization in large projects.

Example:

file class Helper
{
    public static void Assist() => Console.WriteLine("Assisting...");
}
Enter fullscreen mode Exit fullscreen mode

By scoping types to a single file, you can control accessibility and reduce potential conflicts in larger codebases.


9. Improved nameof Expressions

In C# 12, the nameof operator can now be used with parameters, locals, and types. This enhancement makes it easier to work with dynamic code where you need reliable names for variables and types.

Example:

void DisplayName(string paramName)
{
    Console.WriteLine(nameof(paramName)); // Output: "paramName"
}
Enter fullscreen mode Exit fullscreen mode

This small improvement can make debugging and logging easier by allowing you to capture names directly without relying on string literals.


10. With-Expressions for Non-Records

With-expressions, previously exclusive to records, are now available for classes in C# 12. This feature allows you to clone objects with modified properties without altering the original instance.

Example:

var original = new Person { Name = "Alice", Age = 30 };
var modified = original with { Age = 31 };
Enter fullscreen mode Exit fullscreen mode

With-expressions simplify object manipulation, especially in immutable data patterns, and they enhance code readability by reducing unnecessary constructors.


Why You Should Start Using C# 12 Today

These new features in C# 12 are designed to make your code cleaner, more efficient, and easier to maintain. Whether you’re a seasoned developer or just getting started, adopting these features can help you write better C# code with minimal effort.

Conclusion

C# 12 brings powerful new tools that simplify coding and make it more expressive. From primary constructors for non-record classes to enhanced switch expressions and with-expressions for non-records, these updates reduce boilerplate and boost productivity.

By mastering these features, you'll be ready to write cleaner, more maintainable code with the latest that C# has to offer. If you're already using .NET 8 or planning to, upgrading to C# 12 is a no-brainer to take full advantage of the latest language advancements.

Top comments (0)