【问题标题】:C# 7.3 Enum constraint: Why can't I use the nullable enum?C# 7.3 枚举约束:为什么我不能使用可为空的枚举?
【发布时间】:2018-10-25 08:52:17
【问题描述】:

既然我们有枚举约束,为什么编译器不允许我写这段代码?

public static TResult? ToEnum<TResult>(this String value, TResult? defaultValue)
    where TResult : Enum
{
    return String.IsNullOrEmpty(value) ? defaultValue : (TResult?)Enum.Parse(typeof(TResult), value);
}

编译器说:

错误 CS0453 类型“TResult”必须是不可为空的值类型,才能将其用作泛型类型或方法“Nullable”中的参数“T”

【问题讨论】:

  • @DanielleSummers 至少在 C#8 之前我们可以得到可为空的引用类型...
  • @DavidG - 同时我还在等待不可为空的引用类型...
  • @JamesFaix 它不应该是一个新的通用约束。这是相同的约束,在 CIL 中一直有效,但在 C# 中一直受到人为限制,直到 7.3。因此,我不认为将其报告为错误会有用。
  • @KirillKovalenko: System.Enumspecial class(无论如何都不能用作类型参数约束)。它非常特别,它继承自System.ValueType,但却是一个引用类型。 stackoverflow.com/questions/14561338/…
  • @mjwills 因为Enum 基类在.NET 类型层次结构中是一个奇怪的情况,并且从它继承的所有类都是值类型。我认为新的约束类似于classstruct 约束,而不仅仅是允许以前禁止的基类约束。

标签: c# enums roslyn c#-7.3


【解决方案1】:

可以,但必须添加另一个约束:struct 约束。

public static void DoSomething<T>(T? defaultValue) where T : struct, Enum
{
}

【讨论】:

  • 这不是一种解决方法。这正是规格告诉我们要做的@KirillKovalenko
  • @PatrickHofman 你能链接到规格吗?我一定是在阅读中错过了那部分。
  • 因为Nullable&lt;T&gt; 要求Tstruct 类型@thermite。
  • 谢谢@patrick,我在文档中发现它可以为空。我正在查看枚举和泛型的文档...
  • @thermite 你能链接到你找到的文档吗?
【解决方案2】:

因为System.Enum 是一个类,所以您不能声明Nullable&lt;Enum&gt; 类型的变量(因为Nullable&lt;T&gt; 只有在Tstruct 时才可能)。

因此:

Enum? bob = null;

不会编译,你的代码也不会。

这绝对是奇怪的(因为Enum 本身是一个类,但是您在代码中定义的特定Enumstruct)如果您以前没有遇到过它,但它显然是一个class(不是struct)根据docs和源代码。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多