34

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

JuChom
  • 5,717
  • 5
  • 45
  • 78
  • When you view a debug of "stats" what do you see? – BugFinder Jan 03 '17 at 13:56
  • It doesn't compile – JuChom Jan 03 '17 at 13:59
  • What happens if you replace `var stats = await ...` with `(fCount, cCount, aCount) stats = await ...` ? – Gusdor Jan 03 '17 at 14:05
  • I have this error ```error CS1003: Syntax error, '=>' expected``` – JuChom Jan 03 '17 at 14:09
  • Is it definitely using the right compiler? Just wondering since it is in theory possible for the intellisense to be using a different compiler to your actual build. Not sure how that would happen but its the main thing that springs to mind as to why they might disagree.... – Chris Jan 03 '17 at 14:12
  • @Chris How can I check that? – JuChom Jan 03 '17 at 14:15
  • 1
    could deffo be a bug where the Tuple as generic argument is not compiled correctly – Serve Laurijssen Jan 03 '17 at 14:23
  • http://stackoverflow.com/questions/19532942/which-version-of-c-sharp-am-i-using probably still works. I don't really know for sure though having not played with the latest version. Given how new it is though it might well be a bug as Servé says. – Chris Jan 03 '17 at 14:25
  • 5
    Does the code compile if you use generic accessors (i.e. Item1, Item2)? My guess would be that this is a bug. – Sunshine Jan 03 '17 at 14:33
  • I thinks it is because you should return some valid value in GetAllStatsSync(), you are doing this `return (fCount, cCount, aCount);`, but fCount, cCount and aCount are not defined. Take a look at my answer, I modified it according to some comments it has received – Facundo La Rocca Jan 03 '17 at 15:06

4 Answers4

47

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)

JuChom
  • 5,717
  • 5
  • 45
  • 78
  • 2
    Just a note that as of now (I assume VS2017 RTM) 2.0.1 is released and not prerelease. – Rudi Visser Mar 25 '17 at 17:59
  • tnx dear @Swell, you save my time – Imran Sh Apr 17 '17 at 07:34
  • 5
    You are a lifesafer. Code was showing fine in the editor, no errors in the error list, but was showing errors in the output window. A quick search brought up this question, solved the issue right away. – vkapadia Apr 19 '17 at 19:57
1

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.

user4951
  • 32,206
  • 53
  • 172
  • 282
0

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

Facundo La Rocca
  • 3,786
  • 2
  • 25
  • 47
  • 4
    The OP wants to work with value tuples but this uses a record class. – Gusdor Jan 03 '17 at 14:01
  • I'm not too familiar with the new syntax myself but it doesn't look like the non-generic class was used. The `<>` in `Task<(int fCount, int cCount, int aCount)>` certainly make it look generic and I believe the syntax inside that is the new implicit tuple syntax. I'd only seen examples of it used as direct return parameters but the fact that this compiles suggests that this is the way to use it as a generic parameter. – Chris Jan 03 '17 at 14:02
  • I cant find any example using it in the way `Task<(int fCount, int cCount, int aCount)>`. I was almost sure task result is always a TResult, but i'm not familiar with the new sintaxys. I'll trying to find something. Thanks – Facundo La Rocca Jan 03 '17 at 14:11
  • Great!!! I've edited my answer following your recommendation, if you have time take a look at it please. I've learned something new. Thanks – Facundo La Rocca Jan 03 '17 at 14:34
  • The OP simply included a comment that they omitted the body of `GetAllStatsAsync`. If they didn't define those variables then the error message would be completely different than what they're getting. – Servy Jan 03 '17 at 17:52
0

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>
Schwarzie2478
  • 2,186
  • 26
  • 30