1. <ul id="0c1fb"></ul>

      <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
      <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区

      RELATEED CONSULTING
      相關(guān)咨詢
      選擇下列產(chǎn)品馬上在線溝通
      服務(wù)時(shí)間:8:30-17:00
      你可能遇到了下面的問(wèn)題
      關(guān)閉右側(cè)工具欄

      新聞中心

      這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
      如何正確的在C#項(xiàng)目中使用枚舉-創(chuàng)新互聯(lián)

      本篇文章給大家分享的是有關(guān)如何正確的在C#項(xiàng)目中使用枚舉,小編覺(jué)得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說(shuō),跟著小編一起來(lái)看看吧。

      專注于為中小企業(yè)提供成都網(wǎng)站設(shè)計(jì)、網(wǎng)站建設(shè)服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)寶山免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動(dòng)了上千多家企業(yè)的穩(wěn)健成長(zhǎng),幫助中小企業(yè)通過(guò)網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。

      枚舉基礎(chǔ)


      枚舉類型的作用是限制其變量只能從有限的選項(xiàng)中取值,這些選項(xiàng)(枚舉類型的成員)各自對(duì)應(yīng)于一個(gè)數(shù)字,數(shù)字默認(rèn)從 0 開始,并以此遞增。例如:

      public enum Days
      {
       Sunday, Monday, Tuesday, // ...
      }

      其中 Sunday 的值是 0,Monday 是 1,以此類推。為了一眼能看出每個(gè)成員代表的值,一般推薦顯示地將成員值寫出來(lái),不要省略:

      public enum Days
      {
       Sunday = 0, Monday = 1, Tuesday = 2, // ...
      }

      C# 枚舉成員的類型默認(rèn)是 int 類型,通過(guò)繼承可以聲明枚舉成員為其它類型,比如:

      public enum Days : byte
      {
       Monday = 1,
       Tuesday = 2,
       Wednesday = 3,
       Thursday = 4,
       Friday = 5,
       Saturday = 6,
       Sunday = 7
      }

      枚舉類型一定是繼承自 byte、sbyte、short、ushort、int、uint、long 和 ulong 中的一種,不能是其它類型。下面是幾個(gè)枚舉的常見(jiàn)用法(以上面的 Days 枚舉為例):

      // 枚舉轉(zhuǎn)字符串
      string foo = Days.Saturday.ToString(); // "Saturday"
      string foo = Enum.GetName(typeof(Days), 6); // "Saturday"
      // 字符串轉(zhuǎn)枚舉
      Enum.TryParse("Tuesday", out Days bar); // true, bar = Days.Tuesday
      (Days)Enum.Parse(typeof(Days), "Tuesday"); // Days.Tuesday
      
      // 枚舉轉(zhuǎn)數(shù)字
      byte foo = (byte)Days.Monday; // 1
      // 數(shù)字轉(zhuǎn)枚舉
      Days foo = (Days)2; // Days.Tuesday
      
      // 獲取枚舉所屬的數(shù)字類型
      Type foo = Enum.GetUnderlyingType(typeof(Days))); // System.Byte
      
      // 獲取所有的枚舉成員
      Array foo = Enum.GetValues(typeof(MyEnum);
      // 獲取所有枚舉成員的字段名
      string[] foo = Enum.GetNames(typeof(Days));

      另外,值得注意的是,枚舉可能會(huì)得到非預(yù)期的值(值沒(méi)有對(duì)應(yīng)的成員)。比如:

      Days d = (Days)21; // 不會(huì)報(bào)錯(cuò)
      Enum.IsDefined(typeof(Days), d); // false

      即使枚舉沒(méi)有值為 0 的成員,它的默認(rèn)值永遠(yuǎn)都是 0。

      var z = default(Days); // 0

      枚舉可以通過(guò) Description、Display 等特性來(lái)為成員添加有用的輔助信息,比如:

      public enum ApiStatus
      {
       [Description("成功")]
       OK = 0,
       [Description("資源未找到")]
       NotFound = 2,
       [Description("拒絕訪問(wèn)")]
       AccessDenied = 3
      }
      
      static class EnumExtensions
      {
       public static string GetDescription(this Enum val)
       {
        var field = val.GetType().GetField(val.ToString());
        var customAttribute = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute));
        if (customAttribute == null) { return val.ToString(); }
        else { return ((DescriptionAttribute)customAttribute).Description; }
       }
      }
      
      static void Main(string[] args)
      {
       Console.WriteLine(ApiStatus.Ok.GetDescription()); // "成功"
      }

      上面這些我認(rèn)為已經(jīng)包含了大部分我們?nèi)粘S玫降拿杜e知識(shí)了。下面我們繼續(xù)回到文章開頭說(shuō)的用戶角色存儲(chǔ)問(wèn)題。

      用戶角色存儲(chǔ)問(wèn)題

      我們先定義一個(gè)枚舉類型來(lái)表示兩種用戶角色:

      public enum Roles
      {
       Admin = 1,
       Member = 2
      }

      這樣,如果某個(gè)用戶同時(shí)擁有 Admin 和 Member 兩種角色,那么 User 表的 Roles 字段就應(yīng)該存 3。那問(wèn)題來(lái)了,此時(shí)若查詢所有擁有 Admin 角色的用戶的 SQL 該怎么寫呢?對(duì)于有基礎(chǔ)的程序員來(lái)說(shuō),這個(gè)問(wèn)題很簡(jiǎn)單,只要用位操作符邏輯與(‘&')來(lái)查詢即可。

      SELECT * FROM `User` WHERE `Roles` & 1 = 1;

      同理,查詢同時(shí)擁有這兩種角色的用戶,SQL 語(yǔ)句應(yīng)該這么寫:

      SELECT * FROM `User` WHERE `Roles` & 3 = 3;

      對(duì)這條 SQL 語(yǔ)句用 C# 來(lái)實(shí)現(xiàn)查詢是這樣的(為了簡(jiǎn)單,這里使用了 Dapper):

      public class User
      {
       public int Id { get; set; }
       public Roles Roles { get; set; }
      }
      
      connection.Query(
       "SELECT * FROM `User` WHERE `Roles` & @roles = @roles;",
       new { roles = Roles.Admin | Roles.Member });

      對(duì)應(yīng)的,在 C# 中要判斷用戶是否擁有某個(gè)角色,可以這么判斷:

      // 方式一
      if ((user.Roles & Roles.Admin) == Roles.Admin)
      {
       // 做管理員可以做的事情
      }
      
      // 方式二
      if (user.Roles.HasFlag(Roles.Admin))
      {
       // 做管理員可以做的事情
      }

      同理,在 C# 中你可以對(duì)枚舉進(jìn)行任意位邏輯運(yùn)算,比如要把角色從某個(gè)枚舉變量中移除:

      var foo = Roles.Admin | Roles.Member;
      var bar = foo & ~Roles.Admin;

      這就解決了文章前面提到的用整型來(lái)存儲(chǔ)多角色的問(wèn)題,不論數(shù)據(jù)庫(kù)還是 C# 語(yǔ)言,操作上都是可行的,而且也很方便靈活。

      枚舉的 Flags 特性

      下面我們提供一個(gè)通過(guò)角色來(lái)查詢用戶的方法,并演示如何調(diào)用,如下:

      public IEnumerable GetUsersInRoles(Roles roles)
      {
       _logger.LogDebug(roles.ToString());
       _connection.Query(
        "SELECT * FROM `User` WHERE `Roles` & @roles = @roles;",
        new { roles });
      }
      
      // 調(diào)用
      _repository.GetUsersInRoles(Roles.Admin | Roles.Member);

      Roles.Admin | Roles.Member 的值是 3,由于 Roles 枚舉類型中并沒(méi)有定義一個(gè)值為 3 的字段,所以在方法內(nèi) roles 參數(shù)顯示的是 3。3 這個(gè)信息對(duì)于我們調(diào)試或打印日志很不友好。在方法內(nèi),我們并不知道這個(gè) 3 代表的是什么。為了解決這個(gè)問(wèn)題,C# 枚舉有個(gè)很有用的特性:FlagsAtrribute。

      [Flags]
      public enum Roles
      {
       Admin = 1,
       Member = 2
      }

      加上這個(gè) Flags 特性后,我們?cè)賮?lái)調(diào)試 GetUsersInRoles(Roles roles) 方法時(shí),roles 參數(shù)的值就會(huì)顯示為 Admin|Member 了。簡(jiǎn)單來(lái)說(shuō),加不加 Flags 的區(qū)別是:

      var roles = Roles.Admin | Roles.Member;
      Console.WriteLing(roles.ToString()); // "3",沒(méi)有 Flags 特性
      Console.WriteLing(roles.ToString()); // "Admin, Member",有 Flags 特性

      給枚舉加上 Flags 特性,我覺(jué)得應(yīng)當(dāng)視為 C# 編程的一種很好實(shí)踐,在定義枚舉時(shí)盡量加上 Flags 特性。

      解決枚舉值沖突:2 的冪

      到這,枚舉類型 Roles 一切看上去沒(méi)什么問(wèn)題,但如果現(xiàn)在要增加一個(gè)角色:Mananger,會(huì)發(fā)生什么情況?按照數(shù)字值遞增的規(guī)則,Manager 的值應(yīng)當(dāng)設(shè)為 3。

      [Flags]
      public enum Roles
      {
       Admin = 1,
       Member = 2,
       Manager = 3
      }

      能不能把 Manager 的值設(shè)為 3?顯然不能,因?yàn)?Admin 和 Member 進(jìn)行位的或邏輯運(yùn)算(即:Admin | Member) 的值也是 3,表示同時(shí)擁有這兩種角色,這和 Manager 沖突了。那怎樣設(shè)值才能避免沖突呢?既然是二進(jìn)制邏輯運(yùn)算“或”會(huì)和成員值產(chǎn)生沖突,那就利用邏輯運(yùn)算或的規(guī)律來(lái)解決。我們知道“或”運(yùn)算的邏輯是兩邊只要出現(xiàn)一個(gè) 1 結(jié)果就會(huì) 1,比如 1|1、1|0 結(jié)果都是 1,只有 0|0 的情況結(jié)果才是 0。那么我們就要避免任意兩個(gè)值在相同的位置上出現(xiàn) 1。根據(jù)二進(jìn)制滿 2 進(jìn) 1 的特點(diǎn),只要保證枚舉的各項(xiàng)值都是 2 的冪即可。比如:

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


      再往后增加的話就是 16、32、64...,其中各值不論怎么相加都不會(huì)和成員的任一值沖突。這樣問(wèn)題就解決了,所以我們要這樣定義 Roles 枚舉的值:

      [Flags]
      public enum Roles
      {
       Admin = 1,
       Member = 2,
       Manager = 4,
       Operator = 8
      }

      不過(guò)在定義值的時(shí)候要在心中小小計(jì)算一下,如果你想懶一點(diǎn),可以用下面這種“位移”的方法來(lái)定義:

      [Flags]
      public enum Roles
      {
       Admin = 1 << 0,
       Member = 1 << 1,
       Manager = 1 << 2,
       Operator = 1 << 3
      }

      一直往下遞增編值即可,閱讀體驗(yàn)好,也不容易編錯(cuò)。兩種方式是等效的,常量位移的計(jì)算是在編譯的時(shí)候進(jìn)行的,所以相比不會(huì)有額外的開銷。

      以上就是如何正確的在C#項(xiàng)目中使用枚舉,小編相信有部分知識(shí)點(diǎn)可能是我們?nèi)粘9ぷ鲿?huì)見(jiàn)到或用到的。希望你能通過(guò)這篇文章學(xué)到更多知識(shí)。更多詳情敬請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。


      新聞名稱:如何正確的在C#項(xiàng)目中使用枚舉-創(chuàng)新互聯(lián)
      網(wǎng)址分享:http://www.ef60e0e.cn/article/shihi.html
      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区
      1. <ul id="0c1fb"></ul>

        <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
        <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

        馆陶县| 衡阳市| 通榆县| 扶余县| 文登市| 旌德县| 渝北区| 大埔县| 阿巴嘎旗| 家居| 大埔区| 延津县| 信宜市| 宜阳县| 南汇区| 合川市| 博野县| 余姚市| 托里县| 湾仔区| 永登县| 民勤县| 寿宁县| 牡丹江市| 仪陇县| 襄樊市| 鹤庆县| 濮阳市| 宣威市| 集贤县| 大英县| 聊城市| 恭城| 广德县| 祁门县| 永泰县| 类乌齐县| 新巴尔虎右旗| 玉林市| 舞阳县| 祁连县|