【问题标题】:C# Is there a way to put a Null-conditional operator (?) on T?C# 有没有办法在 T 上放置 Null 条件运算符 (?)?
【发布时间】:2021-11-18 10:32:04
【问题描述】:

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

  • x 永远不能是 null
  • y 很有可能成为null

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

这可能吗?来自哪个版本的 C#?

编辑:

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

【问题讨论】:

  • 这不是空条件运算符。 T? 指定一个可为空的类型。对于值类型,它会生成一个Nullable<T> 参数。对于引用类型,它什么也不做,因为它们已经可以为空。在 C# 8 及更高版本中,假设启用了可空类型检查,T 将永远不会接受空值,而 T? 会。你试过了吗?你有遇到什么问题吗?
  • T 是引用类型吗?是的,那么你不能保证“x 永远不能为空”,所以这是一个错误的陈述。如果它是一个值类型,请参阅 Panagiotis 评论。 T(例如int)和Nullable<T>(例如int?)是不同的类型
  • 在 C# 8 及更高版本中,您可以让编译器确保在使用 Nullable Reference TypesT 不会接受任何空值。这只适用于您的代码和编译时支持 NRT 的库(BCL 支持它们)。
  • 关于 Nullable 引用类型的文章——特别是关于泛型的文章——回答了我的问题。谢谢@PanagiotisKanavos!

标签: c# generics null-conditional-operator


【解决方案1】:

我在@PanagiotisKanavos 建议的文档中找到了答案:

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

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

  • 如果T 的类型参数是引用类型,则T? 引用相应的可为空的引用类型。例如,如果Tstring,那么T? 就是string?

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

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

  • 如果T 的类型参数是可空值类型,则T? 引用相同的可空值类型。例如,如果Tint?,那么T? 也是int?

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

【讨论】:

  • Compare 永远不会与 nullable 一起使用。两个对象都有可能为 null,在方法内部进行检查并做出相应的决定。
  • 假设您有一个列表,并且您想将其中的每个项目与不同列表的值进行比较。这是应用程序的全部目的。然后您将遍历列表x 的项目。现在假设列表不能包含null。那么x 永远不能为空。当xnull 时,我想确保异常,因为它不应该能够。使用 T? 最适合我的用例。
  • 那你应该做 List
  • 是的,但是假设您有一个列表列表列表列表列表列表列表等,并且您想让该方法递归,那么最深的项目将不是 List 类型,而是T.
  • 然后你做 IEnumerable 并做 Linq 的 SelectMany 直到它没有变成一个平面列表。
【解决方案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.
}

比较方法不将参数作为可空类型。它们采用纯实例,然后在方法内部根据预期的行为做出决定。

【讨论】:

    猜你喜欢
    • 2016-03-05
    • 2020-11-30
    • 2018-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多