JuChom
JuChom

Reputation: 5989

C# 7 ValueTuple compile error

I'm using VS2017 RC and my application targets net framework 4.6.1.

I have two assemblies referencing System.ValueTuple 4.3

MyProject.Services MyProject.WebApi

In MyProject.Services I have a class with a method like this

public async Task<(int fCount, int cCount, int aCount)> GetAllStatsAsync()
{
    // Some code...
    return (fCount, cCount, aCount);
}

In MyProject.WebApi I have a controller that use this method like that:

public async Task<HttpResponseMessage> GetInfoAsync()
{
    // Some code...
    var stats = await _myClass.GetAllStatsAsync();

    var vm = new ViewModel
             {
                 FCount = stats.fCount,
                 CCount = stats.cCount,
                 ACount = stats.aCount
             };

     return Request.CreateResponse(HttpStatusCode.OK, vm);
}

Intellisense is working and deconstruct the tuple but when I compile it fails without any Error in Error List window. In the output windows I have this errors:

2>MyController.cs(83,31,83,40): error CS1061: 'ValueTuple' does not contain a definition for 'fCount' and no extension method 'fCount' accepting a first argument of type 'ValueTuple' could be found (are you missing a using directive or an assembly reference?) 2>MyController.cs(84,39,84,49): error CS1061: 'ValueTuple' does not contain a definition for 'cCount' and no extension method 'cCount' accepting a first argument of type 'ValueTuple' could be found (are you missing a using directive or an assembly reference?) 2>MyController.cs(85,35,85,40): error CS1061: 'ValueTuple' does not contain a definition for 'aCount' and no extension method 'aCount' accepting a first argument of type 'ValueTuple' could be found (are you missing a using directive or an assembly reference?)

I tried adding the DEMO and DEMO_EXPERIMENTAL build flags but still fails.

Any idea on what's wrong?

EDIT 1:

This code works and stats is well deconstructed. I'm probably hitting a bug.

public async Task<HttpResponseMessage> GetInfoAsync()
{
    // Some code...
    var stats = await _myClass.GetAllStatsAsync();
    var tu = stats.ToTuple();
    var vm = new ViewModel
             {
                 FCount = tu.Item1,
                 CCount = tu.Item2,
                 ACount = tu.Item3
             };

     return Request.CreateResponse(HttpStatusCode.OK, vm);
}

EDIT 2:

Issue open on github here: https://github.com/dotnet/roslyn/issues/16200

Upvotes: 35

Views: 9964

Answers (4)

Schwarzie2478
Schwarzie2478

Reputation: 2276

My problem was not at compile error, but during runtime.

But I suspect the fix is still valid and could help somebody here too.

After switching my project to .Net framework 4.7.2 I had to manually update the hintpath for System.ValueTuple from net461 to net47

<HintPath>..\Solutions\packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll</HintPath>

Upvotes: 0

user4951
user4951

Reputation: 33050

I just want to add to the other answers.

Remove System.valuetuple from references. Otherwise, it doesn't work and I do not know why. Basically, value tuple is already in 4.7.2 and so if you use visual studio 2019 you're all set.

If you use visual studio 2019 and I did, that's what worked for me. I don't exactly know why. No need for nugget. No need to reference that directly.

enter image description here

Target your project to use .net framework 4.7.2 and remove references to valuetuple.

Upvotes: 1

JuChom
JuChom

Reputation: 5989

If anyone falls in the same trap, to fix this you need to update this package: Microsoft.Net.Compilers to 2.0 (you need to show pre-release)

Upvotes: 48

Facundo La Rocca
Facundo La Rocca

Reputation: 3866

I think It is because you've not defined fCount, cCount and aCount. Try this

public async Task<(int fCount, int cCount, int aCount)> GetAllStatsAsync()
{
    // Some code...
    //fCount, cCount, aCount are not defined here, so you should define them

    var fCount = 0;
    var cCount= 0;
    var aCount = 0;
    return (fCount , cCount, aCount );

    //Other ways:
    //return (fCount : 0, cCount: 0, aCount : 0);
    //return new (int fCount , int cCount, int aCount ) { fCount = 0, cCount = 0, aCount = 0 };
}

public async Task<HttpResponseMessage> GetInfoAsync()
{
    // Some code...
    var stats = await _myClass.GetAllStatsAsync();

    var vm = new ViewModel
             {
                 FCount = stats.fCount,
                 CCount = stats.cCount,
                 ACount = stats.aCount
             };

     return Request.CreateResponse(HttpStatusCode.OK, vm);
}

Edited with @Swell suggestion

Take a look at this post

Upvotes: 0

Related Questions