元组 lambda 语法突然在 C# 中不起作用

Tuple lambda syntax suddenly not working in C#

我正在使用 .NET Framework 4.7,我已经实现了几个这样的语法

Task<(bool isSuccess, string message)> DownloadFileResource()

并且它已经通过 var

得到了结果
var downloadResult = await BlobUtils.DownloadFileResource()

但是今天当我打开 visual studio 时,我所有的 var 都转换为 dynamic 类型作为 IDE 的建议,不再是 (bool isSuccess, string message),并在 运行 时抛出错误

 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.

当我放置断点时,它们显示 item1item2 而不是 isSuccessmessage

我通过显式声明进行了测试,它有效吗?很迷茫

简而言之,问题是我长期使用 (bool isSuccess, string message) 函数类型语法的 ValueTuple 并使用 var 正常获取值。 var 知道预期的类型,直到今天它带有 dynamic 类型并关闭所有 isSuccessmessage 属性。

更短:我的预期:(我在 .Net Core 2.1 中测试过)

IDE 的作用:

如何解决?这是一个错误?

isSuccess 不是 ValueTuple<bool, string> 的字段 - 它只是编译器附加到 ValueTuple<bool, string>.Item 的名称,因此 dynamic 无法访问它。

我非常怀疑 IDE 建议 dynamic 该建议的 IDE 代码是什么?

更新

我正在使用 Microsoft Visual Studio Enterprise 2019 版本 16.4.6,它非常清楚 result2dynamicresult2.messagedynamic.

dynamic 表示它将在 运行 时解决,其中 result2 将是 ValueTuple<bool, string>,没有 message 属性 或字段。

这是一个错误,但是您代码中的错误,请注意 IDE。

您可以在 sharplab.io 中查看您的代码。在右侧,您会看到翻译后的代码并将鼠标悬停在源代码上(在左侧),您会看到解释代码的工具提示。

我花了将近10个小时将4.7升级到4.7.2,安装了最新的16.4.6 VS,更新了所有依赖,但仍然报错。

所以我最终通过将所有 var result 更改为显式 (bool isMessage, string message) result 来结束它。真可惜,它无法充分发挥 lambda 元组的真正威力。

------更新

我知道错误是什么,因为我的参数被传递为 dynamic 即使 IDE 知道它是一个字符串,但 var 不能。

public static Task<(bool isSuccess, string message)> TestTuple(string param) => Task.FromResult((true, param));
public static dynamic GetItWillBeBug() => "abc";
public static string GetItWontBeBug() => "abc";

我的调用方式

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);
}

肯定是IDE的一个bug,希望有人能向开发者提出问题。