C# 8 在返回具有可空约束的可空泛型时发出警告
C# 8 gives a warning when returning a nullable generic with nullable constraint
此代码:
public T Foo<T>()
where T : class?
{
return null;
}
给出以下错误:
A null literal introduces a null value when 'T' is a non-nullable
reference type
当我们说 T 可以为空时,我不明白为什么我们不能 return null。如果我们另外尝试 return T?
我们将得到一个错误,即 T
必须是不可空的。
似乎不可能同时具有可空约束和 return 可空结果。
假设你打电话给:
string result = Foo<string>();
result
现在包含 null
。但它是一个 string
,不可为空。
编译器警告您 Foo<T>
可能会在 T
不可为 null 的情况下调用,并且在这种情况下 returning null
将是意外的。
请注意,where T : class?
意味着 T
可能 可以为空,但也可能不是。 string
和 string?
都是允许的。我不相信有任何方式可以说“T
必须 可以为空”。
如果你想说:
T
允许为空
- 当
T
不可为空时,那么这个类型仍然可以returnnull
那你可以这样写:
[return: MaybeNull]
public T Foo<T>()
where T : class?
{
return null!;
}
请注意,MaybeNull
仅适用于方法的契约,而不适用于其主体,这就是我们需要 return null!
的原因。但是,您可以在上面的 SharpLab link 中看到调用者 string result = Foo<string>();
收到了正确的警告。
让我们从基础开始。假设您有一个允许它具有空值的引用类型变量。但是你的程序设计要求它始终不为空,如果遇到空值,它很可能得到 NullReferenceException
。
为了避免此类设计问题,引入了 NullableReference
类型。意味着如果一个引用类型被允许有 null 你应该将它标记为 Nullable
并且任何用法都应该在使用它之前检查 null 值。如果未找到检查,则编译器将生成警告。
如果您阅读 this introductory article on NullableReferenceTypes,您将清楚了解此新功能的目的。
此代码:
public T Foo<T>()
where T : class?
{
return null;
}
给出以下错误:
A null literal introduces a null value when 'T' is a non-nullable reference type
当我们说 T 可以为空时,我不明白为什么我们不能 return null。如果我们另外尝试 return T?
我们将得到一个错误,即 T
必须是不可空的。
似乎不可能同时具有可空约束和 return 可空结果。
假设你打电话给:
string result = Foo<string>();
result
现在包含 null
。但它是一个 string
,不可为空。
编译器警告您 Foo<T>
可能会在 T
不可为 null 的情况下调用,并且在这种情况下 returning null
将是意外的。
请注意,where T : class?
意味着 T
可能 可以为空,但也可能不是。 string
和 string?
都是允许的。我不相信有任何方式可以说“T
必须 可以为空”。
如果你想说:
T
允许为空- 当
T
不可为空时,那么这个类型仍然可以returnnull
那你可以这样写:
[return: MaybeNull]
public T Foo<T>()
where T : class?
{
return null!;
}
请注意,MaybeNull
仅适用于方法的契约,而不适用于其主体,这就是我们需要 return null!
的原因。但是,您可以在上面的 SharpLab link 中看到调用者 string result = Foo<string>();
收到了正确的警告。
让我们从基础开始。假设您有一个允许它具有空值的引用类型变量。但是你的程序设计要求它始终不为空,如果遇到空值,它很可能得到 NullReferenceException
。
为了避免此类设计问题,引入了 NullableReference
类型。意味着如果一个引用类型被允许有 null 你应该将它标记为 Nullable
并且任何用法都应该在使用它之前检查 null 值。如果未找到检查,则编译器将生成警告。
如果您阅读 this introductory article on NullableReferenceTypes,您将清楚了解此新功能的目的。