我有一个参数的Dictionary<string,string>
,并且想要创建一个FormUrlEncodedContent
。请参阅以下示例代码:
var message = new Dictionary<string,string> {{"example", "example"}};
var content = new FormUrlEncodedContent(message);
此代码在禁用nullable的情况下运行良好,但启用它会导致警告(由于我们启用了WarningsAsErrors,因此构建失败(。
Argument of type 'System.Collections.Generic.Dictionary<string,string>' cannot
be used for parameter 'nameValueCollection' of type
'System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string?,string?>>'
in 'System.Net.Http.FormUrlEncodedContent.FormUrlEncodedContent'
due to differences in the nullability of reference types.
我已经通过message.Select(kvp => new KeyValuePair<string?, string?>(kvp.Key, kvp.Value))
解决了这个问题,但这非常冗长、粗糙,而且可能更慢。
有什么建议吗?我是不是错过了一个明显的转换方法,或者FormUrlEncodedContent
类接受KeyValuePair<string?, string?>
是错误的?
我所知道的当前C#的最佳解决方案是使用!
:SharpLab
#nullable enable
using System.Collections.Generic;
using System.Net.Http;
var message = new Dictionary<string,string> {{"example", "example"}};
var content = new FormUrlEncodedContent(message!);
这里的问题是结构和类类型参数是不变的。因此,我们不允许隐式地将KeyValuePair<string, string>
转换为KeyValuePair<string?, string?>
,例如,即使这样做并没有真正的安全问题
针对CCD_ 9提出了一个类似问题的解决方案。也许该语言应该引入一个同时适用于Task
和KeyValuePair
场景的解决方案,并且可能可以扩展到其他场景。
编辑:这个问题还揭示了编译器中的一个错误,某些不允许的嵌套可空性转换不会产生警告。为了避免依赖这个bug,我更改了推荐的解决方案。https://github.com/dotnet/roslyn/issues/53189
!
(零容忍(运算符可以完成以下操作:
var message = new Dictionary<string, string> { { "example", "example" } };
var content = new FormUrlEncodedContent(message!);
我似乎已经找到了使用as
:绕过它的方法
var content = new FormUrlEncodedContent(
message.AsEnumerable() as IEnumerable<KeyValuePair<string?,string?>>);