<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      枚舉位邏輯運算從懵懂到似懂非懂

      枚舉位邏輯運算從懵懂到似懂非懂

      ? 相信能看到這篇文章的同學都是對枚舉的位邏輯運算有了初步的了解,但是又沒有一個全面的認知而來。剛好最近閑來無事,想起來有這么一個邏輯運算方式,簡單且高效,并且自己也僅僅是從其它文章中簡單看到過一些描述,沒有進行過實際的應用。所以今天就分享一下自己的學習過程和Demo,自己做個記錄的同時也希望能幫助到同樣想快速理解的你。

      ? 接下來的分享中會涉及到“對整型運算對象按位進行邏輯運算”相關知識,所以推薦對“位運算符”的概念模糊的同學首先看一下以下文章:C# 位運算及實例計算 - 艾三元 - 博客園 (cnblogs.com)。此文章是在查詢資料過程中個人感覺最簡單清晰好理解“位運算符”的一片文章,看完之后對于后續分享品嘗效果更佳。


      接下來進入正題:

      首先看完整 C# Demo

      using System;
      namespace EnumDemo
      {
          class Program
          {
              static void Main(string[] args)
              {
                  var foo = Roles.蕭炎 | Roles.林動 | Roles.霍雨浩;
                  Console.WriteLine(Convert.ToString((int)foo, 2).PadLeft(4, '0'));
                  Console.WriteLine(Convert.ToString((int)~foo, 2).PadLeft(4, '0'));
                  //foo = foo & ~foo; //清空
                  foo = foo & ~Roles.霍雨浩; //移除具體項,(相同方式下支持移除組合項)
                  Console.WriteLine(Convert.ToString((int)foo, 2).PadLeft(4, '0'));
                  if (foo.HasFlag(Roles.蕭炎)) Console.WriteLine("檢測到蕭炎");
                  if ((foo & Roles.林動) == Roles.林動) Console.WriteLine("檢測到林動");
                  if (foo.HasFlag(Roles.霍雨浩)) Console.WriteLine("檢測到霍雨浩");
      
                  Console.WriteLine(foo.ToString());
                  Console.ReadLine();
              }
          }
      
          [Flags]
          public enum Roles
          {
              蕭炎 = 1 << 0,//1
              林動 = 1 << 1,//2
              霍雨浩 = 1 << 2,//4
              小舞 = 1 << 3,//8
              唐舞麟 = 1 << 4,//16
              戴沐白 = 1 << 5,//32
              朱竹青 = 1 << 6,//64
              奧斯卡 = 1 << 7,//128
              寧榮榮 = 1 << 8,//256
              馬紅俊 = 1 << 9,//512
          }
      }
      
      
      

      運行效果:

      0111
      11111111111111111111111111111000
      0011
      檢測到蕭炎
      檢測到林動
      蕭炎, 林動
      

      我們來拆分代碼進行分析

      枚舉定義部分:
      [Flags]
      public enum Roles
      {
          蕭炎 = 1 << 0,//1
          林動 = 1 << 1,//2
          霍雨浩 = 1 << 2,//4
          小舞 = 1 << 3,//8
          唐舞麟 = 1 << 4,//16
          戴沐白 = 1 << 5,//32
          朱竹青 = 1 << 6,//64
          奧斯卡 = 1 << 7,//128
          寧榮榮 = 1 << 8,//256
          馬紅俊 = 1 << 9,//512
      }
      
      問:為什么我們枚舉定義的值都是2的冪?
      答:
      • 假如我們的權限只有蕭炎,那么我們對應值為1

      • 同理我們的權限只有林動,那么我們對應值為2

      • 同時擁有蕭炎和林動的權限,對應值則直接取(1+2)= 3,代表其既包含蕭炎又包含林動

      • 此時如果霍雨浩的值為3,那么會導致無法區分3到底是“蕭炎+林動”還是單純的“霍雨浩”

      • 既然是二進制邏輯運算“或”會和成員值產生沖突,那就利用邏輯運算或的規律來解決。

        ? 我們知道“或”運算的邏輯是兩邊只要出現一個 1 結果就是 1,比如 1|1、1|0 結果都是 1,只有 0|0 的情況 結果才是 0。那么我們就要避免任意兩個值在相同的位置上出現 1。根據二進制滿 2 進 1 的特點,只要保證 枚舉的各項值都是 2 的冪即可。比如:

        1:  00000001
        2:  00000010
        4:  00000100
        8:  00001000
        

        再往后增加的話就是 16、32、64...,其中各值不論怎么相加都不會和成員的任一值沖突

      問:為什么枚舉值不是直接寫的Int值,而是1 << 0的這種寫法
      答:
      • 此為位左移運算,詳情參考頂部提到的位運算及實例計算,其結果對應后方注釋的Int值。
      • 直接定義Int值需要計算,且肉眼看上去較亂,使用位左移運算簡單明了且有序。
      • 定義方式不唯一,根據個人喜好來定義即可。
      問:枚舉上方的Flags屬性有何作用
      答:
      • 枚舉的 Flags 特性,看碼子說話

        void FlagsSimple()
        {
            var roles = Roles.蕭炎 | Roles.林動;
            // 沒有 Flags 特性輸出結果為:3
            Console.WriteLine(roles.ToString());
            // 有 Flags 特性輸出結果則為:"蕭炎,林動"
            Console.WriteLine(roles.ToString()); 
        }
        
      • 實際使用總結:加上 Flags 特性品嘗效果更佳

      控制臺判斷及輸出部分:
      static void Main(string[] args)
      {
         var foo = Roles.蕭炎 | Roles.林動 | Roles.霍雨浩;
          Console.WriteLine(Convert.ToString((int)foo, 2).PadLeft(4, '0'));
          Console.WriteLine(Convert.ToString((int)~foo, 2).PadLeft(4, '0'));
          //foo = foo & ~foo; //清空
          foo = foo & ~Roles.霍雨浩; //移除具體項,(相同方式下支持移除組合項)
          Console.WriteLine(Convert.ToString((int)foo, 2).PadLeft(4, '0'));
          if (foo.HasFlag(Roles.蕭炎)) Console.WriteLine("檢測到蕭炎");
          if ((foo & Roles.林動) == Roles.林動) Console.WriteLine("檢測到林動");
          if (foo.HasFlag(Roles.霍雨浩)) Console.WriteLine("檢測到霍雨浩");
      
          Console.WriteLine(foo.ToString());
          Console.ReadLine();
      }
      
      • 在C#中用以下方式進行判斷即可:

        if (foo.HasFlag(Roles.蕭炎)) Console.WriteLine("檢測到蕭炎");
        if ((foo & Roles.林動) == Roles.林動) Console.WriteLine("檢測到林動");
        
      附·Sql 品嘗案例:
      • 創建Demo表

        CREATE TABLE [dbo].[PowersDemo](
        	[Id] [int] IDENTITY(1,1) NOT NULL,
        	[Name] [varchar](50) NULL,
        	[PowerNo] [int] NULL,
        	[Powers] [int] NULL,
         CONSTRAINT [PK_PowersDemo] PRIMARY KEY CLUSTERED 
        (
        	[Id] ASC
        )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
        ) ON [PRIMARY]
        GO
        
      • 插入測試數據

        Id Name PowerNo Powers
        1 蕭炎 1 3
        2 林動 2 3
        3 霍雨浩 4 20
        4 小舞 8 12
        5 唐舞麟 16 16
        6 戴沐白 32 100
        7 朱竹青 64 64
        8 奧斯卡 128 384
        9 寧榮榮 256 384
      • 品嘗腳本

        select * from dbo.PowersDemo
        
        --查詢Powers包含霍雨浩權限的角色
        select * from dbo.PowersDemo 
        where Powers & 4 = 4
        
        --移除小舞對霍雨浩的權限
        update dbo.PowersDemo set Powers = Powers & ~4
        where Id = 4
        
        select * from dbo.PowersDemo 
        
        --查詢Powers包含霍雨浩權限的角色
        select * from dbo.PowersDemo 
        where Powers & 4 = 4
        
        --清空小舞對所有角色的權限
        update dbo.PowersDemo set Powers = Powers & ~Powers
        where Id = 4
        
        --查詢小舞的信息
        select * from dbo.PowersDemo 
        

      總結:

      ? 在小型系統中,把用戶角色或權限等直接存儲在用戶表是很常見的做法,此時把角色或權限字段設為整型(比如 int)是比較好的設計方案。但與此同時,也要考慮到一些最佳實踐,比如使用 Flags 特性來幫助更好的調試和日志輸出。也要考慮到實際開發中的各種潛在問題,比如多個枚舉值進行或(‘|’)運算與成員值發生沖突的問題。


      本文參考文章:

      posted @ 2021-06-29 16:07  要有夢想  Views(503)  Comments(2)    收藏  舉報
      主站蜘蛛池模板: 国产免费高清69式视频在线观看 | 亚洲男人AV天堂午夜在| 亚洲性日韩一区二区三区| 九九热在线观看视频免费| 本免费Av无码专区一区| 乌克兰丰满女人a级毛片右手影院| 亚洲十八禁一区二区三区| 亚洲国产成人综合精品| 亚洲国产精品无码久久久秋霞1| 亚洲欧美日韩综合一区在线| 精品国产午夜理论片不卡| 国内精品一区二区在线观看| av色国产色拍| 熟妇的奶头又大又长奶水视频| 九九热精品视频在线免费| 波多野结衣一区二区免费视频| 上饶市| 国产成人免费永久在线平台| 国产一区二区三区亚洲精品| 国产 另类 在线 欧美日韩| 精品免费看国产一区二区| 精品无人区一区二区三区在线 | 国产精品美女一区二三区| 亚洲第一区二区快射影院| 韩国无码AV片午夜福利| 国产区一区二区现看视频| 亚洲aⅴ综合av国产八av| 中国熟女仑乱hd| 少妇高潮尖叫黑人激情在线| 欧美一区二区三区啪啪| 涿鹿县| 国产精品午夜福利片国产| 四虎国产精品永久在线下载| 精品国产一区二区三区av片| 国产欧美日韩视频一区二区三区 | 亚洲天堂av在线免费看| 国产精品一区二区人人爽| av中文无码乱人伦在线观看| 潮喷无码正在播放| 丰满爆乳一区二区三区| 在线aⅴ亚洲中文字幕|