c# - 将 KeyValuePair 枚举传递给 FormUrlEncodedContent 构造函数时,为什么 Visual Studio 会生成警告 CS620?

标签 c# syntax compiler-warnings .net-5

考虑以下代码:

using System;
using System.Collections.Generic;
using System.Net.Http;

namespace dla.test2{
    internal class Test{
        public static void Main(){
            var map=new Dictionary<string,string>(){
                ["hello"]="world"
            };
            using var foo=new FormUrlEncodedContent(map);
        }
    }
}
调用 FormUrlEncodedContent 的构造函数在构建时产生以下编译器警告:

Warning CS8620 Argument of type 'Dictionary<string, string>' cannot be used for parameter 'nameValueCollection' of type 'IEnumerable<KeyValuePair<string?, string?>>' in 'FormUrlEncodedContent.FormUrlEncodedContent(IEnumerable<KeyValuePair<string?, string?>> nameValueCollection)' due to differences in the nullability of reference types.


documentation for FormUrlEncodedContent表示构造函数应该接受 IEnumerable<KeyValuePair<string,string>>? .我的 map变量,是 Dictionary<string,string> , 大概会实现接口(interface) IEnumerable<KeyValuePair<string,string>>所以我希望这里没有问题。 那么为什么会出现警告呢?
我正在使用面向 NETCore5 的 Visual Studio 16.8.0。

最佳答案

我觉得这里实际上有几个问题:

  • 为什么文档有误?并且,
  • 为什么会发出警告。

  • 后者更容易回答。前者,没有那么多(你得问微软)。
    我还没有安装 .NET 5。但是我可以使用以下代码在 .NET Core 3.1 中重现完全相同的警告:
    static void Main(string[] args)
    {
        var map = new Dictionary<string, string>()
        {
            ["hello"] = "world"
        };
    
        M1(map);
    }
    
    static void M1(IEnumerable<KeyValuePair<string?, string?>>? nameValueCollection) { }
    
    可以从您复制/粘贴到问题中的警告中推断出 FormUrlEncodedContent 类构造函数的 .NET 5 版本的实际声明必须是什么,所以我只写了一个不需要安装 .NET 5 的示例。
    事实上,如果我们查看 the source code ,我们可以看到该构造函数的实际声明:
    public FormUrlEncodedContent(IEnumerable<KeyValuePair<string?, string?>> nameValueCollection)
    
    这告诉我文档是不准确的,如果不是完全不正确的话。我没有关注支持可为空引用类型的框架的更改,所以我不确定文档是否会显示这种情况下的可为空类型参数。在我看来应该是,但显然不是。至少,令我惊讶的是,文档将 nameValueCollection 参数本身显示为可以为空(实际上并非如此),更不用说它显示 KeyValuePair<TKey, TValue> 类型参数为不可为空的,而实际上它们可以为空。
    但是无论如何,通过了解 .NET 5 中的实际方法签名是什么,我们可以说警告存在,因为确实,您的调用涉及传递与类型参数的可为空性不一致的类型。
    为什么这会产生警告?嗯……虽然我们知道在这种情况下没有代码将写入可枚举值中的可为空值,但没有编译时保证。由于您的对象正在返回值是不可为空的引用的对象,并且您将其传递给一个声明为接受可为空值的方法,这意味着理论上,该方法可以通过将它们设置为 null 来修改这些可空值, 违反了您自己的代码假设值不可为空。

    关于c# - 将 KeyValuePair 枚举传递给 FormUrlEncodedContent 构造函数时,为什么 Visual Studio 会生成警告 CS620?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64491624/

    相关文章:

    c# - 我可以将 C# 变量管理到 .js 中吗?

    c# - 匹配特定模式的正则表达式

    matlab - ~= 在 MATLAB 中是什么意思?

    python - `If` 行的语法错误

    function - 一个函数是如何工作的

    gcc - 如何在 gitlab CI 中检测编译器警告

    c++ - MSVC C/C++ 编译器未定义行为警告

    c# - 在本地计算机上的何处设置 Microsoft.Bot.Builder.Azure.Utils.GetAppSetting 的值?

    c# - Workflow Foundation 中自定义事件所需参数的默认值

    编译器不会警告 C 数据或精度丢失