当 T 是值类型时,default(T?) 不返回 null

Kis*_*sar 8 c# linq default nullable nullable-reference-types

我遇到过以下现象,并且完全被迷惑了。我正在使用启用了 nullable 的 C# 10。

default(int?)按预期返回 null。然而,以下函数返回任何default(T)内容

public static T? ShouldReturnNull<T>()
{
    return default(T?);
}
Run Code Online (Sandbox Code Playgroud)

在我们得到 0 的情况下,ShouldReturnNull<int>()它不也应该返回 null 吗?

我的程序中有以下代码,这成为一个问题:

public T?[] FindKElements(...)
{
    var result = new (T, double)?[k];


    // ... populate result array,
    // possibly including null values...


    // return an array containing only the T part or null
    return result.Select(e => e is null ? default(T?) : e.Value.Item1).ToArray();
}
Run Code Online (Sandbox Code Playgroud)

有没有办法让它保持通用,但当 T 是值类型时使用适当的空值?编译器不允许我使用null来代替default(T?).

Mar*_*ell 4

在没有约束的情况下where T : structT?并不意味着Nullable<T>;它的意思是“ T,但请注意,它不会null在 NRT 意义上”——并且由于 NRT null永远不会应用于您的值类型场景:它基本上只是意味着T; 并且值类型的默认值T不是null(在任何意义上)。

在需要跨值类型和引用类型场景(包括支持没有值的值类型)的“空检查”的情况下,最简单的方法通常是忘记Nullable<T>并仅跟踪:

  1. 我有一个值吗 ( bool),以及
  2. 值是多少 ( T)

分别且明确地;这可以通过以下任何一种方式:

  • bool SomeMethod(out var T)
  • (HasValue: bool, Value: T) SomeMethod()
  • Maybe<T> SomeMethod()

(其中是由 a和 a组成的Maybe<T>自定义)structbool HasValueT Value

这实际上创建了类似于 的东西Nullable<T>,但它适用于所有值,无论类型如何。无需检查 null ,只需.HasValue先检查,如果为 true,则假设该值有意义。