C# 有没有办法在 T 上放置一个 Null 条件运算符 (?)?

C# Is there a way to put a Null-conditional operator (?) on T?

提问人:Zenith 提问时间:11/18/2021 最后编辑:Zenith 更新时间:11/18/2021 访问量:296

问:

我有一个.这个接口有一个方法。interface<T>Compare(T x, T y)

  • x永远不可能.null
  • y有很大的机会成为.null

我想通过在 : 上使用 Null 条件运算符来明确这一点。?yCompare(T x, T? y)

这是否可能,从哪个版本的 C# 开始?

编辑:

T可以是引用类型和值类型。

C# 泛型 null 条件运算符

评论

3赞 Panagiotis Kanavos 11/18/2021
这不是一个 null 条件运算符。 指定可为 null 的类型。对于值类型,它会生成一个参数。对于引用类型,它不执行任何操作,因为它们已经可以为 null。在 C# 8 及更高版本中,假设启用了可为 null 的类型检查,则永远不会接受 null。你试过吗?你遇到什么问题了吗?T?Nullable<T>TT?
0赞 Liam 11/18/2021
T 是引用类型吗?如果是这样,那么你就不能保证“x 永远不会为空”,所以这是一个错误的陈述。如果是值类型,请参阅 Panagiotis 注释。 (例如)和(例如)是不同的类型TintNullable<T>int?
0赞 Panagiotis Kanavos 11/18/2021
在 C# 8 及更高版本中,可以让编译器确保在使用可为 null 的引用类型时不接受任何 null。这仅适用于在支持 NRT 的情况下编译的代码和库(BCL 支持它们)。T
0赞 Zenith 11/18/2021
关于可以为 null 的引用类型(特别是关于泛型)的文章回答了我的问题。谢谢@PanagiotisKanavos!

答:

0赞 Zenith 11/18/2021 #1

我在@PanagiotisKanavos建议的一份文件中找到了答案:

https://learn.microsoft.com/en-us/dotnet/csharp/nullable-references#generics

在 C# 8.0 中,使用而不约束为 a 或 a 不会编译。这使编译器能够清楚地解释。在 C# 9.0 中,通过为不受约束的类型参数定义以下规则,删除了该限制:T?TstructclassT?T

  • 如果 的类型参数是引用类型,则引用相应的可为 null 的引用类型。例如,如果 是 ,则为 .TT?TstringT?string?

  • 如果 的类型参数是值类型,则引用相同的值类型 。例如,if 是 ,则也是 。TT?TTintT?int

  • 如果 的类型参数是可为 null 的引用类型,则引用相同的可为 null 的引用类型。例如,如果 是 ,则也是 。TT?Tstring?T?string?

  • 如果 的类型参数是可以为 null 的值类型,则引用相同的可为 null 的值类型。例如,如果 是 ,则也是 。TT?Tint?T?int?

对于我的问题,这意味着我需要将 T 限制在一个类中,因为我使用的是 C#8。

评论

0赞 Nikhil Agrawal 11/18/2021
Compare 从不与 nullable 一起使用。这两个对象都有可能为 null,这在方法内部进行检查并相应地做出决定。
0赞 Zenith 11/18/2021
假设您有一个列表,并且想要将其中的每个项目与不同列表的值进行比较。这就是应用程序的全部目的。然后,您将遍历列表项。现在假设列表不能包含 .然后永远不可能为空。我想确保 when is 出现异常,因为它不应该能够。使用最适合我的用例。xnullxxnullT?
0赞 Nikhil Agrawal 11/18/2021
然后你应该做List<T>
0赞 Zenith 11/18/2021
是的,但是假设你有一个列表列表,列表,列表列表等列表,并且你想使方法递归,那么最深的项目将不是List<T类型>而是T类型。
0赞 Nikhil Agrawal 11/18/2021
然后执行 IEnumerable<T> 并执行 Linq 的 SelectMany,直到它不成为平面列表。
0赞 Nikhil Agrawal 11/18/2021 #2

鉴于在写出这个答案之前,没有提到如果有这样的条件T

public interface IDoWork<T> : where T: ???
{...}

我们假设它是一个引用类型

现在假定这是一个引用类型,那么你应该这样做T

public int Compare(T x, T y)
{

    if (y == null)
        //Take decision accordingly.
    else
        //Take decision accordingly.
}

比较方法不将参数作为可为 null 的类型。他们采用纯实例,然后在方法内部根据预期的行为进行决策。