【问题标题】:HasFlag with a generic enum?带有通用枚举的 HasFlag?
【发布时间】:2012-03-01 16:05:07
【问题描述】:

我刚从 C# 中的 Generics 开始,但很早就遇到了问题,如何在通用 Enum 上调用 .HasFlag()

public class Example<TEnum> where TEnum : struct {
}

如何添加[Flags] 属性?

【问题讨论】:

  • 简而言之,你不能。约束不考虑泛型参数的属性。你必须通过反思来强制执行。
  • 类型参数应该以T开头;您应该将GenericEnum 更改为TEnum
  • 你能举个例子@M.Babcock 吗?并正式指出,@SLaks
  • 如果你愿意,你也可以使用John Skeet's library来强制枚举约束。
  • @AnuragRanjhan 上面的库链接返回 404 错误。能更新一下吗?

标签: c# generics enums enum-flags


【解决方案1】:

调用实例方法无论如何都需要装箱,所以,既然你不能约束到Enum,就放弃泛型并使用Enum。例如,而不是:

void Something(TEnum enumValue, TEnum flags)
{
    if (enumValue.HasFlags(flags))
        //do something ...
}

这样做:

void Something(Enum enumValue, Enum flags)
{
    if (enumValue.HasFlags(flags))
        //do something ...
}

在通用方法中,您可以这样实现目标:

void Something(TEnum enumValue, TEnum flags)
{
    Enum castValue = (Enum)(object)enumValue;
    Enum castFlags = (Enum)(object)flags;

    if (castValue.HasFlags(castFlags))
        //do something ...
}

如果您使用不是枚举的值类型调用该方法,这将在运行时引发异常。您也可以通过ValueType 而不是object 进行转换,因为已知类型参数代表值类型:

Enum castValue = (Enum)(ValueType)enumValue;

【讨论】:

  • 我最初按照您的建议进行操作,但正在尝试将使用您的示例的几种方法重构为一个采用通用枚举并且仍然能够调用具有标志的方法
  • @Tyler 我添加了一个示例,展示了如何将泛型类型参数的实例转换为Enum
  • 感谢@phoog。我仍在努力解决它,但注意到 HasFlag() 方法已出现在智能感知中!
  • @Tyler 不客气。另请注意,即使您的 type 参数是没有 Flags 属性的枚举,HasFlags 方法也将起作用。如果要防止在非标志枚举上调用 HasFlags,则需要使用反射进行运行时检查。如果您在类的静态构造函数中执行该检查,它几乎不会对性能产生任何影响。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-08
  • 2020-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多