不可用的枚举作为通用参数

发布于 2025-01-29 08:06:02 字数 342 浏览 3 评论 0原文

我正在尝试在C#7.3中实现此辅助功能:

public static T? ToEnum<T>(this string enumName)
    where T : Enum 
    => Enum.TryParse<T>(enumName, out T val) ? val : null;

但是有一个编译器错误:

错误CS8370功能“无效的参考类型”在C#7.3

中不可用

为什么编译器认为我使用可确定的参考类型,而T则被限制为eNUM哪个已经是值类型?

I am trying to implement this helper function in C# 7.3:

public static T? ToEnum<T>(this string enumName)
    where T : Enum 
    => Enum.TryParse<T>(enumName, out T val) ? val : null;

But got a compiler error:

Error CS8370 Feature 'nullable reference types' is not available in C# 7.3

Why does the compiler think I am using a nullable reference type while T is constrained to be an Enum which is a value type already?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

山色无中 2025-02-05 08:06:02

此问题不是特定于 nullable 枚举。即使您使用了不可用的枚举,它也行不通。这是因为虽然特定的枚举类型是价值类型,但system.enum是一种参考类型,如说明在这里。因此,除 enum约束外,您还需要添加struct约束

以下内容应有效:

public static T? ToEnum<T>(this string enumName) 
    where T : struct, Enum
    => Enum.TryParse<T>(enumName, out T val) ? val : default(T?);

另外,请注意,您不能在三元运算符的第二个分支中使用null,因为编译器无法推断该类型。使用默认(t?)而不是。

用法的示例:

enum MyEnum { a, b, c }

static void Main(string[] args)
{
    var e1 = "b".ToEnum<MyEnum>();
    var e2 = "d".ToEnum<MyEnum>();

    Console.WriteLine("e1 = " + (e1?.ToString() ?? "NULL"));  // e1 = b
    Console.WriteLine("e2 = " + (e2?.ToString() ?? "NULL"));  // e2 = NULL
}

This problem is not specific to nullable enums. Even if you use a non-nullable enum, it won't work. That's because while specific enum types are value types, System.Enum is a reference type as explained here. So, you need to add a struct constraint in addition to the Enum constraint.

The following should work:

public static T? ToEnum<T>(this string enumName) 
    where T : struct, Enum
    => Enum.TryParse<T>(enumName, out T val) ? val : default(T?);

Also, note that you can't use null in the second branch of the ternary operator because the compiler can't infer the type. Use default(T?) instead.

Example of usage:

enum MyEnum { a, b, c }

static void Main(string[] args)
{
    var e1 = "b".ToEnum<MyEnum>();
    var e2 = "d".ToEnum<MyEnum>();

    Console.WriteLine("e1 = " + (e1?.ToString() ?? "NULL"));  // e1 = b
    Console.WriteLine("e2 = " + (e2?.ToString() ?? "NULL"));  // e2 = NULL
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文