What's new in C# 7.3?

borrrden

Jim Borden

Posted on April 26, 2018

What's new in C# 7.3?

Visual Studio 15.7 Preview 3 has shipped initial support for some C# 7.3 features. Let's see what they are!

System.Enum, System.Delegate and unmanaged constraints.

Now with generic functions you can add more control over the types you pass in. More specifically, you can specify that they must be enum types, delegate types, or "blittable" types. The last one is a bit involved, but it means a type that consists only of certain predefined primitive types (such as int or UIntPtr), or arrays of those types. "Blittable" means it has the ability to be sent as-is over the managed-unmanaged boundary to native code because it has no references to the managed heap. This means you have the ability to do something like this:

void Hash<T>(T value) where T : unmanaged
{
    fixed (T* p = &value) { 
        // Do stuff...
    }
}
Enter fullscreen mode Exit fullscreen mode

I'm particularly excited about this one because I've had to use a lot of workarounds to be able to make helper methods that work with "pointer types."

Ref local re-assignment

This is just a small enhancement to allow you to assign ref type variables / parameters to other variables the way you do normal ones. I think the following code is an example (off the top of my head)

void DoStuff(ref int parameter)
{
    // Now otherRef is also a reference, modifications will 
    // propagate back
    var otherRef = ref parameter;

    // This is just its value, modifying it has no effect on 
    // the original
    var otherVal = parameter;
}
Enter fullscreen mode Exit fullscreen mode

Stackalloc initializers

This adds the ability to initialize a stack allocated array (did you even know this was a thing in C#? I did :D) as you would a heap allocated one:

Span<int> x = stackalloc[] { 1, 2, 3 };.
Enter fullscreen mode Exit fullscreen mode

Indexing movable fixed buffers

I can't really wrap my head around this one so see if you can understand it

Custom fixed statement

This is the first I've seen this one, and it is exciting for me! Basically, if you implement an implicit interface (one method), you can use your own types in a fixed statement for passing through P/Invoke. I'm not sure what the exact method is (DangerousGetPinnableReference() or GetPinnableReference()) since the proposal and the release notes disagree but if this method returns a suitable type then you can eliminate some boilerplate.

Improved overload candidates

There are some new method resolution rules to optimize the way a method is resolved to the correct one. See the propsal for a list of the.

Expression Variables in Initializers

The summary here is "Expression variables like out var and pattern variables are allowed in field initializers, constructor initializers, and LINQ queries." but I am not sure what that allows us to do...

Tuple comparison

Tuples can be compared with == and != now!

Attributes on backing fields

Have you ever wanted to put an attribute (e.g. NonSerializable) on the backing field of a property, and then realized that you then had to create a manual property and backing field just to do so?

[Serializable]
public class Foo {
    [NonSerialized]
    private string MySecret_backingField;

    public string MySecret {
        get { return MySecret_backingField; }
        set { MySecret_backingField = value; }
    }
}
Enter fullscreen mode Exit fullscreen mode

Not anymore!

[Serializable]
public class Foo {
    [field: NonSerialized]
    public string MySecret { get; set; }
}
Enter fullscreen mode Exit fullscreen mode
πŸ’– πŸ’ͺ πŸ™… 🚩
borrrden
Jim Borden

Posted on April 26, 2018

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related