当前位置:  开发笔记 > 编程语言 > 正文

C#:Enum.IsDefined在组合标志上

如何解决《C#:Enum.IsDefined在组合标志上》经验,为你挑选了3个好方法。

我有这个枚举:

[Flags]
public enum ExportFormat
{
    None = 0,
    Csv = 1,
    Tsv = 2,
    Excel = 4,
    All = Excel | Csv | Tsv
}

我试图在这个(或任何,真正的)枚举上做一个包装,它通知变化.目前它看起来像这样:

public class NotifyingEnum : INotifyPropertyChanged
    where T : struct
{
    private T value;

    public event PropertyChangedEventHandler PropertyChanged;

    public NotifyingEnum()
    {
        if (!typeof (T).IsEnum)
            throw new ArgumentException("Type T must be an Enum");
    }

    public T Value
    {
        get { return value; }
        set
        {
            if (!Enum.IsDefined(typeof (T), value))
                throw new ArgumentOutOfRangeException("value", value, "Value not defined in enum, " + typeof (T).Name);

            if (!this.value.Equals(value))
            {
                this.value = value;

                PropertyChangedEventHandler handler = PropertyChanged;
                if (handler != null)
                    handler(this, new PropertyChangedEventArgs("Value"));
            }
        }
    }
}

由于枚举可以真正分配任何值,我想检查是否定义了给定的值.但我发现了一个问题.如果我在这里给它一个由例如组成的枚举Csv | Excel,那么Enum.IsDefined将返回false.显然是因为我没有定义任何由这两个组成的枚举.我想在某种程度上是合乎逻辑的,但我应该如何检查给定值是否有效?换句话说,为了使它工作,我需要交换以下这一行?

if (!Enum.IsDefined(typeof (T), value))

Frans Bouma.. 9

使用基于标志的枚举,它是关于设置与否.因此,对于'ExportFormat',如果设置了第1位,则它是CSV格式,即使可能设置了更多位.第1位和第2位是否设置了无效值?这是主观的:从作为一个组的值的角度来看,它是无效的(没有为第1和第2位设置定义的位模式)但是,因为每个值都是一个位,单独查看它们,它可能是位1和2设置的值有效.

如果传入值0011111011,那是否是有效值?好吧,这取决于你在寻找什么:如果你正在查看整个值,那么它是一个无效的值,但如果你正在查看单个位,它是一个正确的值:它设置的位不是定义,但没关系,因为基于标志的枚举是"每位"检查的:你没有将它们与一个值进行比较,而是检查是否设置了一个位.

因此,由于您的逻辑将检查设置哪些位来选择要选择的格式,因此无需检查枚举值是否已定义:您有3种格式:如果设置了相应格式的位,则格式为选择.这是你应该写的逻辑.



1> Frans Bouma..:

使用基于标志的枚举,它是关于设置与否.因此,对于'ExportFormat',如果设置了第1位,则它是CSV格式,即使可能设置了更多位.第1位和第2位是否设置了无效值?这是主观的:从作为一个组的值的角度来看,它是无效的(没有为第1和第2位设置定义的位模式)但是,因为每个值都是一个位,单独查看它们,它可能是位1和2设置的值有效.

如果传入值0011111011,那是否是有效值?好吧,这取决于你在寻找什么:如果你正在查看整个值,那么它是一个无效的值,但如果你正在查看单个位,它是一个正确的值:它设置的位不是定义,但没关系,因为基于标志的枚举是"每位"检查的:你没有将它们与一个值进行比较,而是检查是否设置了一个位.

因此,由于您的逻辑将检查设置哪些位来选择要选择的格式,因此无需检查枚举值是否已定义:您有3种格式:如果设置了相应格式的位,则格式为选择.这是你应该写的逻辑.



2> Dan McCann..:

我们知道转换为字符串的枚举值永远不会以数字开头,但总是会有一个无效值的数字.这是最简单的解决方案:

public static bool IsDefinedEx(this Enum yourEnum)
{
    char firstDigit = yourEnum.ToString()[0];
    if (Char.IsDigit(firstDigit) || firstDigit == '-')  // Account for signed enums too..
        return false;

    return true;
}

使用该扩展方法而不是库存IsDefined,这应该可以解决您的问题.


您可能还想检查字符' - ',因为枚举可以用有符号值表示.

3> Treb..:

我将在位级操作并检查是否在您的All值中设置了新值中设置的所有位:

if ( ! (All & NewValue) == NewValue )

您将不得不看到自己如何做到这一点,也许您需要将所有值转换为int然后执行按位比较.

推荐阅读
wurtjq
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有