无法将不可为 null 的对象作为接受 nullalble 的参数传递
Cannot pass a non-nullable object as a parameter that accepts nullalble
我有这个简单的代码,它生成了一个警告:
private void MyMethod()
{
IDictionary<string, object> notNullable = new Dictionary<string, object>();
Test(notNullable);
}
private void Test(IDictionary<string, object?> nullable)
{
}
我在尝试编译时收到此警告(但它确实适用于 !):
Argument of type 'Dictionary< string, object>' cannot be used for
parameter 'nullable' of type 'IDictionary' in '...'
due to differences in the nullability of reference types
现在我可以通过相反的方式看到问题,但是我将不可为空的参数发送到可为空的参数是怎么回事?只是 C# 编译器的限制,或者可能是一个错误?
这与通用类型参数 covariance/contravariance problem because IDictionary
supports "in and out" 数据移动(与 IReadOnlyDictionary
相比,后者是 "out" 容器)是同一个问题。
它 不编译 发出警告的原因是因为它允许这样做:
// 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
和 out
注释其泛型类型参数,而具体类型(包括抽象 类)不能。这不是问题,前提是将使用泛型类型的程序(期望类型参数变化)编程为使用接口而不是具体类型。
在 C# 7.0 之前,您不需要这个 object?
因为类型对象接受可为 null 的值,与字符串相同。例如,如果它是 int
那么你需要这样做 IDictionary<string, int?>
我有这个简单的代码,它生成了一个警告:
private void MyMethod()
{
IDictionary<string, object> notNullable = new Dictionary<string, object>();
Test(notNullable);
}
private void Test(IDictionary<string, object?> nullable)
{
}
我在尝试编译时收到此警告(但它确实适用于 !):
Argument of type 'Dictionary< string, object>' cannot be used for parameter 'nullable' of type 'IDictionary' in '...' due to differences in the nullability of reference types
现在我可以通过相反的方式看到问题,但是我将不可为空的参数发送到可为空的参数是怎么回事?只是 C# 编译器的限制,或者可能是一个错误?
这与通用类型参数 covariance/contravariance problem because IDictionary
supports "in and out" 数据移动(与 IReadOnlyDictionary
相比,后者是 "out" 容器)是同一个问题。
它 不编译 发出警告的原因是因为它允许这样做:
// 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
和 out
注释其泛型类型参数,而具体类型(包括抽象 类)不能。这不是问题,前提是将使用泛型类型的程序(期望类型参数变化)编程为使用接口而不是具体类型。
在 C# 7.0 之前,您不需要这个 object?
因为类型对象接受可为 null 的值,与字符串相同。例如,如果它是 int
那么你需要这样做 IDictionary<string, int?>