c# - 不能将不可为空的对象作为接受 nullalble 的参数传递
问题描述
我有这个简单的代码,它会生成一个警告:
private void MyMethod()
{
IDictionary<string, object> notNullable = new Dictionary<string, object>();
Test(notNullable);
}
private void Test(IDictionary<string, object?> nullable)
{
}
当我尝试编译时收到此警告(但它确实可以使用!):
由于引用类型的可空性不同,“...”中“IDictionary”类型的参数“可空”不能使用“字典<字符串,对象>”类型的参数
现在我可以看到相反的问题,但是我将不可为空的参数发送到可空参数有什么问题?只是 C# 编译器的限制,或者可能是一个错误?
解决方案
这与泛型参数协方差/逆变问题是相同的问题,因为IDictionary
支持数据的“进出”移动(与之相比IReadOnlyDictionary
是“出”容器)。
它的原因不编译发出警告是因为它允许这样做:
// This code requires a C# 8.0 compiler!
private void MyMethod()
{
IDictionary<String,Object> cannotContainNulls = new Dictionary<String,Object>();
Test( cannotContainNulls );
assert( cannotContainNulls[ "this has a null value" ] == null ); // this shouldn't be possible!
}
private void Test( IDictionary<String,Object?> canContainNulls )
{
canContainNulls.Add( key: "this has a null value", value: null );
}
如果你改变你的Test
方法来接受一个IReadOnlyDictionary
(其中TValue
标记out
为逆变(或协方差,我忘了哪个是哪个)它应该起作用。
请注意,只有接口和委托才能将其泛型类型参数用in
and注释out
,而具体类型(包括抽象类)则不能。如果使用期望类型参数变化的泛型类型的程序被编程为使用接口而不是具体类型,这不是问题。
推荐阅读
- docker - 在 docker 中使用具有隐身模式的 puppeteer-extra
- javascript - 禁用滚动`` 在反应
- python - 调用某个 url 后在烧瓶中运行后台任务
- python - Python argparse 将参数保存到变量中
- python - 如何使用使用 AngularJS ng-include 的网站在 python 中进行 Webscrape
- azure-active-directory - Microsoft Teams 与 Moodle LMS 的集成
- flutter - 在 TextAlign.center 或 TextAlign.right 中颤动 textField 光标
- c++ - 虚函数,什么时候用?
- html - 为什么使用 css 的 zindex 值较低的元素会出现在 z-index 较高的元素之上?
- magento - 停止 Braintree 付款方式的自动发票生成