为可为 Null 的枚举添加约束

发布于 2024-09-24 21:10:00 字数 1289 浏览 1 评论 0原文

我正在编写一些枚举功能,并具有以下功能:

public static T ConvertStringToEnumValue<T>(string valueToConvert, bool isCaseSensitive)
{
    if (typeof(T).BaseType.FullName != "System.Enum" && typeof(T).BaseType.FullName != "System.ValueType")
    {
       throw new ArgumentException("Type must be of Enum and not " + typeof (T).BaseType.FullName);
    }

    if (String.IsNullOrWhiteSpace(valueToConvert))
      return (T)typeof(T).TypeInitializer.Invoke(null);

    valueToConvert = valueToConvert.Replace(" ", "");              

    if (typeof(T).BaseType.FullName == "System.ValueType")
    {
        return (T)Enum.Parse(Nullable.GetUnderlyingType(typeof(T)), valueToConvert, !isCaseSensitive);
    }

    return (T)Enum.Parse(typeof(T), valueToConvert, !isCaseSensitive);
}

我这样称呼它:

EnumHelper.ConvertStringToEnumValue<Enums.Animals?>("Cat");

我现在想将 T 的约束添加到枚举,例如(我从 Stackoverflow 文章): where T : struct, IConvertible 但我遇到了 T 的问题需要能够采用可为空的枚举。错误消息说:

类型“Enums.Animals?”必须是不可为 null 的值类型才能将其用作泛型类型或方法中的参数“T”

有没有办法做到这一点,或者我是否只需要依赖于方法内部的运行时检查?

谢谢大家!

I'm writing some Enum functionality, and have the following:

public static T ConvertStringToEnumValue<T>(string valueToConvert, bool isCaseSensitive)
{
    if (typeof(T).BaseType.FullName != "System.Enum" && typeof(T).BaseType.FullName != "System.ValueType")
    {
       throw new ArgumentException("Type must be of Enum and not " + typeof (T).BaseType.FullName);
    }

    if (String.IsNullOrWhiteSpace(valueToConvert))
      return (T)typeof(T).TypeInitializer.Invoke(null);

    valueToConvert = valueToConvert.Replace(" ", "");              

    if (typeof(T).BaseType.FullName == "System.ValueType")
    {
        return (T)Enum.Parse(Nullable.GetUnderlyingType(typeof(T)), valueToConvert, !isCaseSensitive);
    }

    return (T)Enum.Parse(typeof(T), valueToConvert, !isCaseSensitive);
}

I call it like this:

EnumHelper.ConvertStringToEnumValue<Enums.Animals?>("Cat");

I now want to add constraints to T to an Enum, such as (which I got from Stackoverflow article): where T : struct, IConvertible but I am having problems as T needs to be able to take nullable enums. Error message says:

The type 'Enums.Animals?' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method

Is there a way to do this, or do I need to just rely on the runtime checking which I have inside the method?

Thanks all!

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

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

发布评论

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

评论(2

沉睡月亮 2024-10-01 21:10:00

不,没有任何约束说“T 必须是值类型,包括可为 null 的值类型”。

然而,一种选择是将方法分为:

public static T ConvertStringToEnumValue<T>(...) where T : struct
public static T? ConvertStringToNullableEnumValue<T>(...) where T : struct

除了其他任何事情之外,每个方法的实现也会更简单。

当然,我们不知道您将如何使用此代码 - 但如果您要从非泛型方法直接调用它,这将是我建议的方法。

当然,这仍然无法阻止有人用 T=int 或类似的东西来调用它......你可能想看看 Unconstrained Melody 用于更严格的约束。

No, there's no constraint which says "T must be a value type, including nullable value types."

One option, however, would be to split the method into to:

public static T ConvertStringToEnumValue<T>(...) where T : struct
public static T? ConvertStringToNullableEnumValue<T>(...) where T : struct

Aside from anything else, each method's implementation would then be simpler, too.

Of course, we don't know how you're going to use this code - but if you're going to call it directly from non-generic methods, this would be my suggested approach.

Of course, that's still not going to stop someone from calling it with T=int or something like that... you might want to look at Unconstrained Melody for more rigid constraints.

忆离笙 2024-10-01 21:10:00

有一个涉及 C++/CLI 的技巧,它允许对枚举进行通用约束。使用 C++/CLI 编写带有 Enum 约束的抽象基类。在 C# 项目中引用该库并实现基类。

There is a trick that involves C++/CLI which does allow generic constraints on Enums. Write a base abstract class in C++/CLI with the Enum constraint. Reference the library in a C# project and implement the base class.

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