What's new in C# 7.3?
Jim Borden
Posted on April 26, 2018
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...
}
}
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;
}
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 };.
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; }
}
}
Not anymore!
[Serializable]
public class Foo {
[field: NonSerialized]
public string MySecret { get; set; }
}
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
January 6, 2022
October 4, 2021