首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >确定Enum标志组合中包含的标志数量的最佳实践?

确定Enum标志组合中包含的标志数量的最佳实践?
EN

Stack Overflow用户
提问于 2016-05-01 05:08:46
回答 2查看 1.5K关注 0票数 4

在某些情况下,当我将Enum传递给一个方法时,我需要处理它是单个Enum值,还是它是一个标志组合,为此,我编写了这个简单的扩展:

Vb.Net:

代码语言:javascript
复制
<Extension>
Public Function FlagCount(ByVal sender As System.[Enum]) As Integer
    Return sender.ToString().Split(","c).Count()
End Function

C# (在线翻译):

代码语言:javascript
复制
[Extension()]
public int FlagCount(this System.Enum sender) {
    return sender.ToString().Split(',').Count();
}

示例用法:

Vb.Net:

代码语言:javascript
复制
Dim flags As FileAttributes = (FileAttributes.Archive Or FileAttributes.Compressed)
Dim count As Integer = flags.FlagCount()
MessageBox.Show(flagCount.ToString())

C# (在线翻译):

代码语言:javascript
复制
FileAttributes flags = (FileAttributes.Archive | FileAttributes.Compressed);
int count = flags.FlagCount();
MessageBox.Show(flagCount.ToString());

我只想问一问,是否存在一种更直接、更有效的方式,即我目前为避免将标志组合表示为字符串,然后拆分它所做的事情。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-05-01 06:05:04

选项A:

代码语言:javascript
复制
public int FlagCount(System.Enum sender)
{
    bool hasFlagAttribute = sender.GetType().GetCustomAttributes(typeof(FlagsAttribute), false).Length > 0;
    if (!hasFlagAttribute) // No flag attribute. This is a single value.
        return 1;

    var resultString = Convert.ToString(Convert.ToInt32(sender), 2);
    var count = resultString.Count(b=> b == '1');//each "1" represents an enum flag.
    return count;
}

解释:

  • 如果枚举没有"Flags属性“,那么它一定是一个值。
  • 如果枚举具有“标志”属性,则将其转换为位表示并计数"1"s.每个"1“表示一个枚举标志。

选项B:

  1. 把所有的东西都拿来。
  2. 数一数..。

守则:

代码语言:javascript
复制
public int FlagCount(this System.Enum sender)
{
  return sender.GetFlaggedValues().Count;
}

/// <summary>
/// All of the values of enumeration that are represented by specified value.
/// If it is not a flag, the value will be the only value returned
/// </summary>
/// <param name="value">The value.</param>
/// <returns></returns>
public static List<Enum> GetFlaggedValues(this Enum value)
{
    //checking if this string is a flagged Enum
    Type enumType = value.GetType();
    object[] attributes = enumType.GetCustomAttributes(true);

    bool hasFlags = enumType.GetCustomAttributes(true).Any(attr => attr is System.FlagsAttribute);
    //If it is a flag, add all flagged values
    List<Enum> values = new List<Enum>();
    if (hasFlags)
    {
        Array allValues = Enum.GetValues(enumType);
        foreach (Enum currValue in allValues)
        {
            if (value.HasFlag(currValue))
            {
                values.Add(currValue);
            }
        }
    }
    else//if not just add current value
    {
        values.Add(value);
    }
    return values;
}
票数 6
EN

Stack Overflow用户

发布于 2017-05-13 21:40:19

不能让这件事过去。在整数中计数位时的最佳做法是不转换为字符串.我们是否已经失去了使用bits的能力,现在我们都使用高级语言?)

由于问题是关于最有效的执行,下面是我的答案。我还没有试过过度优化它,因为这样做会混淆它,我认为。我还使用了前面的答案作为基础,使比较更容易。有两种方法,一种是计数标志,另一种是如果您只想知道它是否有单个标志,就提前退出。注意:您不能删除标志属性检查,因为标准的非标志枚举也可以是任何数字。

代码语言:javascript
复制
    public static int FlagCount(this System.Enum enumValue){
        var hasFlagAttribute = enumValue.GetType().GetCustomAttributes(typeof(FlagsAttribute), false).Length > 0;
        if (!hasFlagAttribute)
            return 1;
        var count = 0;
        var value = Convert.ToInt32(enumValue);
        while (value != 0){
            if ((value & 1) == 1)
                count++;
            value >>= 1;
        }
        return count;
    }
    public static bool IsSingleFlagCount(this System.Enum enumValue){
        var hasFlagAttribute = enumValue.GetType().GetCustomAttributes(typeof(FlagsAttribute), false).Length > 0;
        if (!hasFlagAttribute)
            return true;
        var isCounted = false;
        var value = Convert.ToInt32(enumValue);
        while (value != 0){
            if ((value & 1) == 1){
                if (isCounted)
                    return false;
                isCounted = true;
            }
            value >>= 1;
        }
        return true;
    }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36963279

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档