What's New in C# 7.3?

A look at the small but useful new features introduced in C# 7.3, including tuple equality, enum constraints, and performance improvements for working with `in` parameters.

While not a major version release, C# 7.3, which shipped in May 2018, brought a collection of small but welcome improvements to the language. These features continue the theme of making C# more convenient for everyday coding and enabling higher performance in low-level scenarios.

Let's look at some of the most useful additions in C# 7.3.

1. Tuple Equality

C# 7.0 introduced a powerful new syntax for creating and working with tuples. C# 7.3 enhances this by making tuples comparable with the == and != operators.

var tuple1 = (a: 1, b: 2);
var tuple2 = (a: 1, b: 2);

// In C# 7.3, this now works as you would expect.
if (tuple1 == tuple2)
{
    Console.WriteLine("The tuples are equal."); // This will be printed
}

The comparison is done element by element, from left to right. This makes tuples even more useful for simple data structures and for returning multiple values from a method.

2. Enum Constraints in Generics

You can now specify System.Enum as a constraint for a generic type parameter. This allows you to write generic utility methods that work with any enum type in a type-safe way.

// This method will only accept types that are enums.
public static string GetEnumName<T>(T value) where T : System.Enum
{
    return Enum.GetName(typeof(T), value);
}

// Usage
string sunday = GetEnumName(DayOfWeek.Sunday);

3. in Overload Resolution

C# 7.2 introduced the in parameter modifier, which allows you to pass arguments by reference in a read-only manner, avoiding unnecessary copying of large structs. C# 7.3 improves how the compiler resolves method overloads with in parameters, making it easier to work with them without ambiguity.

4. Expression Variables in More Places

C# 7.0 introduced out variables, allowing you to declare a variable right at the point where it is passed as an out argument. C# 7.3 expands where you can use these expression variables, such as in field initializers and query clauses.

Example in a constructor initializer:

public class MyClass
{
    private int _value;

    public MyClass(string s) : this(int.TryParse(s, out var i) ? i : 0)
    {
    }

    public MyClass(int value)
    {
        _value = value;
    }
}

5. Attach Attributes to the Backing Fields of Auto-Properties

Sometimes you need to attach an attribute to the compiler-generated backing field of an auto-implemented property (for example, to control serialization). C# 7.3 introduces a new field: specifier for attributes to make this possible.

public class MyData
{
    [field: NonSerialized]
    public string MyProperty { get; set; }
}

Conclusion

C# 7.3 is a point release focused on developer quality of life and performance. While it doesn't contain any headline-grabbing features, the small improvements to tuples, generics, and in parameters all contribute to making the language more pleasant and efficient to work with. These incremental refinements are a key part of the C# language's continued evolution.

Comments

Share your thoughts and insights in the comments below. We'd love to hear your perspective on this topic!

Geek Cafe LogoGeek Cafe

Your trusted partner for cloud architecture, development, and technical solutions. Let's build something amazing together.

Quick Links

© 2025 Geek Cafe LLC. All rights reserved.

Research Triangle Park, North Carolina

Version: 8.9.22