zoukankan      html  css  js  c++  java
  • 原创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吧

  • 相关阅读:
    ubuntu 制做samba
    《Programming WPF》翻译 第4章 前言
    《Programming WPF》翻译 第4章 3.绑定到数据列表
    《Programming WPF》翻译 第4章 4.数据源
    《Programming WPF》翻译 第5章 6.触发器
    《Programming WPF》翻译 第4章 2.数据绑定
    《Programming WPF》翻译 第4章 1.不使用数据绑定
    《Programming WPF》翻译 第5章 7.控件模板
    《Programming WPF》翻译 第5章 8.我们进行到哪里了?
    《Programming WPF》翻译 第5章 5.数据模板和样式
  • 原文地址:https://www.cnblogs.com/goldli/p/3179132.html
Copyright © 2011-2022 走看看