Search code examples
c#roslynvaluetuple

How does the System.ValueTuple NuGet expand my language features?


If using .Net < 4.7 tuples are not supported. If I install the NuGet "System.ValueTuple", I'm able to write code like

    public static (string Name, int Age) GetFoo()
    {
        return ("Bar", 99);
    }

with .Net 4.6.2. How is that possible? How can a NuGet (DLL) change my available language features? Is there any documentation available about what is going on here? I wasn't able to find any.


Solution

  • The compiler simply needs certain features to exist to bind to them. In the case of (string Name, int Age) it is looking for System.ValueTuple<T1,T2> - and as long as it finds that, it is happy. It doesn't usually matter from where - if it comes from the current runtime system library: fine; if it comes from a nuget package: also fine!

    This has a lot of pedigree; this same approach applies to a lot of things:

    • "LINQ" - just needs the right methods to resolve, whether by extension methods or not (this has allowed "LinqBridge", for example, to retro-fit LINQ onto older runtimes)
    • async/await - just needs the GetAwaiter() etc methods to exist, whether by extension methods or not
    • async iterator blocks and async foreach - just needs the IAsyncEnumerable<T> etc APIs to exist (and the correct builder APIs for async iterators)
    • async dispose - just needs the IAsyncDisposable interface to exist
    • etc

    so .NET and C# have enjoyed a long history of allowing nuget packages (or other library updates) to "light up" C# features that are designed for "current" frameworks.

    Without those methods / types / etc being available, the compiler still knows about the feature - it just can't use it unless it knows how to attach. If the type / method resolves: you're golden.