返回类型为泛型的函数不能返回 Null

问题描述 投票:0回答:1

如果我有一个类型,比如

int
,我可以通过在其末尾添加一个问号来使其可为空。例如,以下代码可以编译:

int? x = null;

而下面的代码,删除了问号,却没有:

int x = null; //throws a build error

我的理解是我可以对任何类型执行此操作;只需在其末尾添加一个问号,我总是可以为其分配一个空值。

但是,由于某种原因,这不适用于通用函数。考虑以下几点:

T? ReturnNull<T>() => null;

它抛出编译器错误 CS0403:

CS0403: 无法将 null 转换为类型参数“T”,因为它可能是不可为 null 的值类型。考虑使用 default('T') 代替。

什么!?如果我将问号添加到任何类型(类或结构)的名称中,我可以为其分配一个空值,并且它可以正常工作!

有趣的是,如果我要求

T
是一个类或一个结构:

T? ReturnNull<T>() where T : class => null;
T? ReturnNull<T>() where T : struct => null;

效果很好。我虽然可以通过重载上述两个函数来解决这个问题(一个类型可能不能同时是类和结构,对吧?)。

不,我不能。我想错了。以下引发构建错误:

T? ReturnNull<T>() where T : class => null;
T? ReturnNull<T>() where T : struct => null;

CS0128: 在此范围内已定义名为“ReturnNull”的局部变量或函数

什么!?我可以通过改变参数来重载函数!为什么不能通过更改泛型参数的类型约束来重载函数?类和结构不重叠!永远!

我很困惑。我对我的 IDE 非常友善,没有嘲笑它或其他任何事情;那不是问题。为什么这不起作用?

c# generics compiler-errors nullable type-constraints
1个回答
0
投票

请不要同时提出多个问题。

“如果我有一个类型,比如

int
,我可以通过在其末尾添加一个问号来使其可为空”。不,你不能!
int
int?
不是同一类型。一个是整数,另一个是可为空的整数。仅仅因为 c# 现在支持可为 null 的整数,并不意味着不可为 null 的整数已经消失。您的原始代码无法编译,正是因为该语言仍然提供不可为空的类型。

“为什么我不能通过改变类型约束来重载..”因为它还没有实现。这些问题在这里都是题外话。这相当于问为什么猪不能飞:因为上帝/进化没有为它们提供翅膀。为什么在这种情况下是无法回答的。

© www.soinside.com 2019 - 2024. All rights reserved.