This is the first of a series of blog posts where I discuss the upcoming feature proposals for C# 7. At the time that I am writing these posts, these are all proposals. They may change form, or may not be delivered with C# 7, or ever. Each post will include links to the proposal issue on GitHub so that you can follow along with the ongoing disussions on the features.
This is an interesting time for C#. The next version of the language is being designed in the open, with comments and discussion from the team members and the community as the team determines what features should be added to the language.
Ref Returns and Local are described in the Roslyn Repository on GitHub, in Issue #118.
What is Ref Return and Ref Locals?
This proposal adds C# support for returning values from methods by reference. In addition, local variables could be declared as ‘ref
’ variables. A method could return a reference to an internal data structure. Instead of returning a copy, the return value would be a reference to the internal storage:
ref PhysicalObject GetAsteroid(Position p)
{
int index = p.GetIndex();
return ref Objects[index];
}
ref var a = ref GetAsteroid(p);
a.Explode();
Once the language defines ref
return values, it’s a natural extension to also have ref
local variables, to refer to heap allocated storage by reference:
ref PhysicalObject obj = ref Objects[index];
This enables scenarios where you want to pass references to internal structures without resorting to unsafe code (pointers to pinned memory). Those mechanisms are both unsafe and inefficient.
Why Is It Useful?
Returning values by reference can improve performance in cases where the alternative is either pinned memory, or copying resources. This features enables developers to continue to use verifiably safe code, while avoiding unnecessary copies.
It may not be a feature you use on a daily basis, but for algorithms that require large amounts of memory for different structures, this feature can have a significant positive impact on the performance of your application.
Verifying Object Lifetimes
One of the interesting design challenges around this feature is to ensure that the reference being returned is reachable after being returned. The compiler will ensure that the object returned by a ref
return continues to be reachable after the method has exited. If the object would be unreachable, and subject to garbage collection, that will cause a compiler error.
Effectively, this means you would not be able to return a ref
to a local variable, or a parameter that was not a ref
parameter. There is a lengthy discussion in the GitHub comments that goes into quite a bit of detail on how the compiler can reason about the lifetime of any object that would be returned by reference.