原创C# 枚举 多状态 操作

C# 中枚举类型是一种值类型,目前(vs2012)还不能用于泛型。

此类型最多的用处是标识一组相同类型的状态量或常量,比如:

状态量

示例一

  [Flags]

  public enum ConnectionState

  {

    Closed = 0,

    Open = 1,

    Connecting = 2,

    Executing = 4,

    Fetching = 8,

    Broken = 16,

  }

 常量

示例二

  [Flags]

  [ComVisible(true)]

  [Serializable]

  public enum FileAttributes

  {

    ReadOnly = 1,

    Hidden = 2,

    System = 4,

    Directory = 16,

    Archive = 32,

    Device = 64,

    Normal = 128,

    Temporary = 256,

    SparseFile = 512,

    ReparsePoint = 1024,

    Compressed = 2048,

    Offline = 4096,

    NotContentIndexed = 8192,

    Encrypted = 16384,

    [ComVisible(false)] IntegrityStream = 32768,

    [ComVisible(false)] NoScrubData = 131072,

  }

 在使用中,平时使用频率最多的是:使用switch case 语句来判断枚举中的一个值,比如:

示例三

    enum ActionStep

    {

        /// <summary>

        /// 第一步:打开主页

        /// </summary>

        Home,   

        

        /// <summary>

        /// 第二步:查找输入框与提交按钮,输入关键字后提交

        /// </summary>

        FindAndQuery,      



        /// <summary>

        /// 第三步:查找指定连接,找到后导航到它

        /// </summary>

        Search,            



        /// <summary>

        /// 第四步:等待15秒后关闭

        /// </summary>

        WaittingForClose,



        End

    }

 

                switch (action.Step)

                {

                    case ActionStep.Home:

                        Navigate(task.Home);

                        break;

                    case ActionStep.FindAndQuery:

                        InputAndSubmit(task);

                        break;

                    case ActionStep.Search:

                        SearchTarget(task);

                        break;

                    case ActionStep.WaittingForClose:

                        WaitForClose(task);

                        break;

                }

 然而,我们有时候也需要多状态的情况,比如:文件属性 FileAttributes。

那么,如何来操作呢?

正常的思路是声明一个变量,在需要的时候进行    操作。(不是还有hasFlag嘛?......),比如:C# Enum设计和使用的相关技巧 中的示例

示例四

 例如定义了权限Enum Permission:



[Flags]



public enum Permission{



      Select = 1,



      Edit = 2,



      Delete = 4,



      View = 8,   



      All = Select | Edit | Delete | View



  } 



可以采用这个函数进行计算:



public static Permission ClearFlag(Permission value, Permission flag)  



{       



    value = value & (Permission.All^ flag);



    return value;



}

 使用起来应该很方便,但是如果遇到,像下面的情况

示例五

 [Flags]

    public enum AuthorState

    {

        BlogListDownloading = 1,

        BlogListParsing = 2,



        BlogDownloading = 4,

        BlogParsing = 8,

        BlogWritting = 16,



        MetaDownloading = 32,

        MetaParsing = 64,

        MetaWritting = 128,

        MetasParsedDone = 2048,//所的的元素解析全部完成



        DownloadList = 256,

        CheckUpdate = 512,

        NeedUpdate = 1024//需要更新

        

    }

 

    /// <summary>

    /// 状态辅助类

    /// </summary>

    public class EnumHelper

    {

        private AuthorState _state;



        /// <summary>

        /// 添加一个状态

        /// </summary>

        /// <param name="state"></param>

        public void In(AuthorState state)

        {

            if (!Include(state))

                _state |= state;

        }



        /// <summary>

        /// 删除一个状态

        /// </summary>

        /// <param name="state"></param>

        public void Out(AuthorState state)

        {

            if(!Include(state))

                _state ^= state;

            //_state ^= state;

        }



        /// <summary>

        /// 判断一个状态是否在其中

        /// </summary>

        /// <param name="state"></param>

        /// <returns></returns>

        public bool Include(AuthorState state)

        {

            return (_state & state) == state;

        }

    }

 

 State.In(AuthorState.DownloadList);

            _download.DownloadBlogList(url);

            State.Out(AuthorState.DownloadList); 

 

 即,添加了一个状态,在之后的操作中会去除这个状态。

然而,我在写出了示例五之后总感觉这样做代码量增加太多了,虽然有智能提示。很是怀想delphi下的 In 操作:

示例六

procedure TForm1.Edit1KeyPress(Sender: TObject; var..Key: Char);

begin

  if not(key in['0'..'9',#8])then

  begin

    key:=#0;

    MessageBeep(1);    //Beep; 调用系统声音也行!

  end;

end;

 C#中的In是不会让你这么用的,那么,要怎么办?扩展!扩展枚举,增加一些方法

google了一下,找到了 如何:为枚举创建新方法(C# 编程指南)

下面是我修改之后的代码

示例七

 
[Flags]

    public enum MyEnum

    {

        Zero =1 , One = 2, Two = 4, Three =8

    }

 扩展

    public static class Extensions

    {

        public static MyEnum Host = MyEnum.One;



        public static bool Contained(this MyEnum value)

        {

            return (Host & value) == value;

        }



        public static void Add(this MyEnum value)

        {

            if (value.Contained()) return;

            Host |= value;

        }



        public static void Remove(this MyEnum value)

        {

            if (value.Contained())

                Host ^= value;

        }

    }

 使用方法

    public class  TestCls

    {

        private MyEnum _initValue = MyEnum.One;



        public void Test(MyEnum value)

        {

            Extensions.Host = _initValue;//控制变量

            value.Contained();

            value.Add();

            value.Remove();

        }

    }

 那么,好吧,你现在会用了。

示例八

            MyEnum.One.Add();

            MyEnum.One.Remove();

 去吧,骚年,去Coding吧

 

你可能感兴趣的:(C#)