问题
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