【发布时间】:2020-10-22 22:56:38
【问题描述】:
考虑以下代码:
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 的构造函数会在构建时产生以下编译器警告:
警告 CS8620 'Dictionary
' 类型的参数不能使用 对于类型的参数“nameValueCollection” 'IEnumerable >' 在 'FormUrlEncodedContent.FormUrlEncodedContent(IEnumerable > nameValueCollection)' 由于可空性不同 引用类型。
documentation for FormUrlEncodedContent 表示构造函数应该接受IEnumerable<KeyValuePair<string,string>>?。我的map 变量是Dictionary<string,string>,大概会实现接口IEnumerable<KeyValuePair<string,string>>,所以我希望这里没有问题。 那么为什么会出现警告?
我正在使用面向 NETCore5 的 Visual Studio 16.8.0。
【问题讨论】:
-
因为
string!=string?(例如“由于引用类型的可空性不同”)。 -
但是当一个可以为空的字符串(字符串?)被期望时,不能像我在这里一样,总是作为参数提交一个非空字符串吗?我理解“字符串?”表示字符串可以为空或非空,但也许我误解了。
-
"不能是非空字符串...总是在需要可空字符串(字符串?)时作为参数提交?" -- 不能作为类型参数,没有。就此而言,它也不允许(没有警告)作为引用参数。您需要记住,类型的这些位置涉及输入和输出;保证您不会传递空值是不够的……如果被调用的方法最终提供了一个空值,您还需要保证您可以接受一个空值。请参阅下面的解释。
-
请注意,泛型类型差异正确地遵守了可空性规则。 IE。
IEnumerable<string?>参数可以接受IEnumerable<string>,因为协变类型参数承诺提供的值只是输出,而不是输入,同样IEnumerable<string>参数不会接受IEnumerable<string?>,因为a后者可能会返回空值,而前者只需要非空值。这也适用于逆变类型参数(即,...<in T>用于接口声明),但当然是另一个方向。
标签: c# syntax compiler-warnings .net-5