问题
I'm using .NET Framework 4.7, I have implemented several of syntax like this
Task<(bool isSuccess, string message)> DownloadFileResource()
And it already worked by getting there result with var
var downloadResult = await BlobUtils.DownloadFileResource()
But today when I open visual studio, all my var transform to dynamic type as a suggestion from IDE, not a (bool isSuccess, string message) anymore, and throw error when running it
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException:
'System.ValueTuple<bool,string>' does not contain a definition for > 'isSuccess'
at CallSite.Target(Closure , CallSite , Object )
at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)
at DataUnitCrawler.MainFormV3.<DownloadFileResource>d__10.MoveNext() in D:\Gannha\GannhaDesktopApp\DataUnitCrawler\MainFormV3.cs:line 97
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at DataUnitCrawler.MainFormV3.<<-ctor>b__9_1>d.MoveNext() in D:\Gannha\GannhaDesktopApp\DataUnitCrawler\MainFormV3.cs:line 86
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<>c.<ThrowAsync>b__6_0(Object state)
************** Loaded Assemblies ************** mscorlib
Assembly Version: 4.0.0.0
Win32 Version: 4.8.4121.0 built by: NET48REL1LAST_C
CodeBase: file:///C:/Windows/Microsoft.NET/Framework/v4.0.30319/mscorlib.dll
---------------------------------------- DataUnitCrawler
Assembly Version: 1.0.0.0
Win32 Version: 1.0.0.0
CodeBase: file:///D:/Gannha/GannhaDesktopApp/DataUnitCrawler/bin/Debug/DataUnitCrawler.exe
---------------------------------------- System.Windows.Forms
Assembly Version: 4.0.0.0
Win32 Version: 4.8.4121.0 built by: NET48REL1LAST_C
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System.Windows.Forms/v4.0_4.0.0.0__b77a5c561934e089/System.Windows.Forms.dll
---------------------------------------- System
Assembly Version: 4.0.0.0
Win32 Version: 4.8.4001.0 built by: NET48REL1LAST_C
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System/v4.0_4.0.0.0__b77a5c561934e089/System.dll
---------------------------------------- System.Drawing
Assembly Version: 4.0.0.0
Win32 Version: 4.8.3752.0 built by: NET48REL1
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System.Drawing/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll
---------------------------------------- System.Data
Assembly Version: 4.0.0.0
Win32 Version: 4.8.4121.0 built by: NET48REL1LAST_C
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_32/System.Data/v4.0_4.0.0.0__b77a5c561934e089/System.Data.dll
---------------------------------------- System.Core
Assembly Version: 4.0.0.0
Win32 Version: 4.8.4121.0 built by: NET48REL1LAST_C
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System.Core/v4.0_4.0.0.0__b77a5c561934e089/System.Core.dll
---------------------------------------- System.Xml
Assembly Version: 4.0.0.0
Win32 Version: 4.8.3752.0 built by: NET48REL1
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System.Xml/v4.0_4.0.0.0__b77a5c561934e089/System.Xml.dll
---------------------------------------- DataUtility
Assembly Version: 1.0.0.0
Win32 Version: 1.0.0.0
CodeBase: file:///D:/Gannha/GannhaDesktopApp/DataUnitCrawler/bin/Debug/DataUtility.DLL
---------------------------------------- Microsoft.WindowsAzure.Storage
Assembly Version: 9.3.2.0
Win32 Version: 9.3.2.0
CodeBase: file:///D:/Gannha/GannhaDesktopApp/DataUnitCrawler/bin/Debug/Microsoft.WindowsAzure.Storage.DLL
---------------------------------------- Microsoft.CSharp
Assembly Version: 4.0.0.0
Win32 Version: 4.8.3752.0
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/Microsoft.CSharp/v4.0_4.0.0.0__b03f5f7f11d50a3a/Microsoft.CSharp.dll
---------------------------------------- System.Configuration
Assembly Version: 4.0.0.0
Win32 Version: 4.8.3752.0 built by: NET48REL1
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System.Configuration/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Configuration.dll
---------------------------------------- Newtonsoft.Json
Assembly Version: 12.0.0.0
Win32 Version: 12.0.1.22727
CodeBase: file:///D:/Gannha/GannhaDesktopApp/DataUnitCrawler/bin/Debug/Newtonsoft.Json.DLL
---------------------------------------- System.Numerics
Assembly Version: 4.0.0.0
Win32 Version: 4.8.3752.0 built by: NET48REL1
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System.Numerics/v4.0_4.0.0.0__b77a5c561934e089/System.Numerics.dll
---------------------------------------- System.Runtime.Serialization
Assembly Version: 4.0.0.0
Win32 Version: 4.8.4121.0 built by: NET48REL1LAST_C
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System.Runtime.Serialization/v4.0_4.0.0.0__b77a5c561934e089/System.Runtime.Serialization.dll
---------------------------------------- System.Dynamic
Assembly Version: 4.0.0.0
Win32 Version: 4.8.3752.0
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System.Dynamic/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Dynamic.dll
---------------------------------------- Anonymously Hosted DynamicMethods Assembly
Assembly Version: 0.0.0.0
Win32 Version: 4.8.4121.0 built by: NET48REL1LAST_C
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_32/mscorlib/v4.0_4.0.0.0__b77a5c561934e089/mscorlib.dll
---------------------------------------- NLog
Assembly Version: 4.0.0.0
Win32 Version: 4.5.11.8645
CodeBase: file:///D:/Gannha/GannhaDesktopApp/DataUnitCrawler/bin/Debug/NLog.DLL
---------------------------------------- NLog.Windows.Forms
Assembly Version: 4.0.0.0
Win32 Version: 4.2.3.167
CodeBase: file:///D:/Gannha/GannhaDesktopApp/DataUnitCrawler/bin/Debug/NLog.Windows.Forms.DLL
---------------------------------------- System.ServiceModel
Assembly Version: 4.0.0.0
Win32 Version: 4.8.4121.0 built by: NET48REL1LAST_C
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System.ServiceModel/v4.0_4.0.0.0__b77a5c561934e089/System.ServiceModel.dll
---------------------------------------- Microsoft.Azure.Storage.Blob
Assembly Version: 11.1.1.0
Win32 Version: 11.1.1
CodeBase: file:///D:/Gannha/GannhaDesktopApp/DataUnitCrawler/bin/Debug/Microsoft.Azure.Storage.Blob.DLL
---------------------------------------- Microsoft.Azure.Storage.Common
Assembly Version: 11.1.1.0
Win32 Version: 11.1.1.0
CodeBase: file:///D:/Gannha/GannhaDesktopApp/DataUnitCrawler/bin/Debug/Microsoft.Azure.Storage.Common.DLL
---------------------------------------- System.Net.Http
Assembly Version: 4.2.0.0
Win32 Version: 4.6.26011.01
CodeBase: file:///D:/Gannha/GannhaDesktopApp/DataUnitCrawler/bin/Debug/System.Net.Http.DLL
----------------------------------------
************** JIT Debugging ************** To enable just-in-time (JIT) debugging, the .config file for this application or computer
(machine.config) must have the jitDebugging value set in the
system.windows.forms section. The application must also be compiled
with debugging enabled.
For example:
<configuration>
<system.windows.forms jitDebugging="true" /> </configuration>
When JIT debugging is enabled, any unhandled exception will be sent to
the JIT debugger registered on the computer rather than be handled by
this dialog box.
When I put a breakpoint, they show item1, item2 instead of isSuccess, message
I tested by declaring explicitly and it worked? That's very confused
For short, the problem is I have used ValueTuple of (bool isSuccess, string message) function type syntax for a long time and got value normally with var. The var knew expected the type until today it comes with dynamic type and off all isSuccess, message attributes.
Shorter: what I expected: (I tested in .Net Core 2.1)
What IDE does:
How to solve it? It's a bug?
回答1:
isSuccess is not a field of ValueTuple<bool, string>- It's just a name the compiler attahces to ValueTuple<bool, string>.Item and, thus, dynamic can't get to it.
I very much doubt the IDE suggested dynamic what was the IDE code of that suggestion?
Update
I'm using Microsoft Visual Studio Enterprise 2019 Version 16.4.6 and it knows pretty well that result2 is dynamic and that result2.message is dynamic.
dynamic means that it will be resolved at run-time where result2 will be a ValueTuple<bool, string>, which doesn't have a message property or field.
It's a bug, but a bug in your code, note the IDE.
You can look at your code in sharplab.io. On the right side you'll see the translated code and hovering the source code (on the left), you'll see tooltips explaining the code.
回答2:
I have spent almost 10 hours to upgrade 4.7 to 4.7.2, installed newest 16.4.6 VS, updated all dependencies, but still gets error.
So I finally end it up by change all var result to explicit (bool isMessage, string message) result. Just so sad that it can't get full real power of lambda tuple.
------ Update
I got what the bug is, because my parameter is passed as dynamic even IDE knew it was a string, but the var cannot.
public static Task<(bool isSuccess, string message)> TestTuple(string param) => Task.FromResult((true, param));
public static dynamic GetItWillBeBug() => "abc";
public static string GetItWontBeBug() => "abc";
My calling method
static async Task Main(string[] args)
{
var result1 = await TestTuple(GetItWontBeBug());
var result2 = await TestTuple(GetItWillBeBug());
Console.WriteLine("It won't be crashed");
Console.WriteLine(result1.message);
Console.WriteLine("It will be crashed");
Console.WriteLine(result2.message);
}
It certainly is a bug of IDE and hope someone could raise the problem to developer.
来源:https://stackoverflow.com/questions/60632521/tuple-lambda-syntax-suddenly-not-working-in-c-sharp