C# - 返回枚举?来自静态扩展方法

发布于 2024-08-07 17:57:20 字数 1305 浏览 6 评论 0原文

我为字符串添加了一些扩展方法,以便更轻松地使用一些自定义枚举。

public static Enum ToEnum<T>(this string s)
{
    return (Enum)Enum.Parse(typeof(T), s);
}

public static bool IsEnum<T>(this string s)
{
    return Enum.IsDefined(typeof(T), s);
}

注意 - 由于泛型类型约束的限制,我必须编写如上所述的方法。我很想使用 T ToEnum(this string s) where T: Enum 来避免调用后的强制转换...但没有办法。

无论如何,我认为稍微扩展这个概念以返回 Enum 会很好吗?在方法签名可以接受各种可为空枚举的情况下。

public static Enum? ToEnumSafe<T>(this string s)
{
    return (IsEnum<T>(s) ? (Enum)Enum.Parse(typeof(T), s) : null);
}

然而,由于编译器错误,这是不可能的。

error CS0453: The type 'System.Enum' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'System.Nullable<T>'

我不得不承认我在这里有点困惑作为枚举?应该是一个合法的返回值,不是吗?我尝试了类似的方法,但最终出现了相同的错误。

public static T? ToEnumSafe<T>(this string s)
{
    return (IsEnum<T>(s) ? (T)Enum.Parse(typeof(T), s) : null);
}

我什至决定重写方法来删除泛型,我得到了更多相同的东西:

public static bool IsEnum(this string s, Type T)
{
    return Enum.IsDefined(T, s);
}
public static Enum? ToEnumSafe(this string s, Type T)
{
    return (IsEnum(s, T) ? (Enum)Enum.Parse(T, s) : null);
}

我在这里错过了一些非常愚蠢的东西吗?

I've added some extension methods for strings to make working with some custom enums easier.

public static Enum ToEnum<T>(this string s)
{
    return (Enum)Enum.Parse(typeof(T), s);
}

public static bool IsEnum<T>(this string s)
{
    return Enum.IsDefined(typeof(T), s);
}

Note -- because of limitations of generic type constraints, I have to write the methods like the above. I would love to use T ToEnum(this string s) where T: Enum to avoid the cast after making the call ... but no can do.

In any event, I figured it would be nice to extend this concept a little bit to return Enum? in those instances where a method signature can accept various nullable enums.

public static Enum? ToEnumSafe<T>(this string s)
{
    return (IsEnum<T>(s) ? (Enum)Enum.Parse(typeof(T), s) : null);
}

However, this is a no-go due to compiler errors.

error CS0453: The type 'System.Enum' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'System.Nullable<T>'

I have to admit I'm a bit confused here as Enum? should be a legitimate return value, no?. I tried something similar, but end up with the same error.

public static T? ToEnumSafe<T>(this string s)
{
    return (IsEnum<T>(s) ? (T)Enum.Parse(typeof(T), s) : null);
}

I even decided to rewrite the methods to remove the generics and I get more of the same:

public static bool IsEnum(this string s, Type T)
{
    return Enum.IsDefined(T, s);
}
public static Enum? ToEnumSafe(this string s, Type T)
{
    return (IsEnum(s, T) ? (Enum)Enum.Parse(T, s) : null);
}

Am I missing something really stupid here?

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

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

发布评论

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

评论(4

屌丝范 2024-08-14 17:57:20

尝试:

public static T? ToEnumSafe<T>(this string s) where T : struct
{
    return (IsEnum<T>(s) ? (T?)Enum.Parse(typeof(T), s) : null);
}

Try:

public static T? ToEnumSafe<T>(this string s) where T : struct
{
    return (IsEnum<T>(s) ? (T?)Enum.Parse(typeof(T), s) : null);
}
拥有 2024-08-14 17:57:20

实际上,你可以做得比这更好——只需做一些工作。

尽管 C# 不支持 T 必须是枚举类型的泛型约束,但 CLR 支持。我有一个名为 Unconstrained Melody 的项目,它是一个“有用的事情”的库一个枚举。”我怀疑它已经可以满足您的需求(只要您只需要使用枚举中的名称,而不是整数值的字符串表示形式)。虽然它没有 IsDefined(string),但它有 TryParse 可以完成相同的工作。

请参阅此博文了解更多详情。

至于为什么 Enum? 不是有效的返回类型 - System.Enum 本身是一个引用类型(就像 System.ValueType),所以它已经可以为空了。您只能将 ? 与不可为空值类型一起使用。

You can actually do somewhat better than this - with a bit of work.

Although C# doesn't support generic constraints to say that T must be an enum type, the CLR does. I have a project called Unconstrained Melody which is a library of "useful things to do with an enum." I suspect it already copes with what you want (so long as you only need to use the names in the enum, not the string representations of the integer values). Although it doesn't have IsDefined(string), it does have TryParse which will do the same job.

See this blog post for more details.

As to why Enum? isn't a valid return type - System.Enum itself is a reference type (just like System.ValueType), so it's already nullable. You can only use ? with non-nullable value types.

十二 2024-08-14 17:57:20
public static Enum ToEnum<T>(this string s)
{
    return (Enum)Enum.Parse(typeof(T), s);
}

应该

public static T ToEnum<T>(this string s)
{
    return (T)Enum.Parse(typeof(T), s);
}

还可以修复以下

public static Enum? ToEnumSafe<T>(this string s)
{
    return (IsEnum<T>(s) ? (Enum)Enum.Parse(typeof(T), s) : null);
}

问题

public static T? ToEnumSafe<T>(this string s)
    where T : struct
{
    return (IsEnum<T>(s) ? (T?)Enum.Parse(typeof(T), s) : null);
}
public static Enum ToEnum<T>(this string s)
{
    return (Enum)Enum.Parse(typeof(T), s);
}

should be

public static T ToEnum<T>(this string s)
{
    return (T)Enum.Parse(typeof(T), s);
}

can also fix the following

public static Enum? ToEnumSafe<T>(this string s)
{
    return (IsEnum<T>(s) ? (Enum)Enum.Parse(typeof(T), s) : null);
}

to

public static T? ToEnumSafe<T>(this string s)
    where T : struct
{
    return (IsEnum<T>(s) ? (T?)Enum.Parse(typeof(T), s) : null);
}
っ〆星空下的拥抱 2024-08-14 17:57:20

枚举在 .Net 中没有明显的类型,它只是具体值类型的占位符(如果您没有另外指定,则为 int )。

这意味着您根本不能将其作为类型声明(无论是否使用静态扩展方法)。

An Enum is no distinct Type in .Net it is just a placeholder for a concrete value type (int in case you didn't specify otherwise).

That means you cant have it as type declaration at all (regardless of static extention method or not).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文