15.1 枚举类型

  • 枚举定义的符号是常量值. C#编译器编译时,会用数值替换符号,不再引用定义了符号的枚举类型.可能会出现一些版本问题.
  • Enum.IsDefined(Type enumType, object value)方法被经常用于参数校验:
        public void SetColor(ConsoleColor c)
{
if (!Enum.IsDefined(typeof(ConsoleColor), c))
{
throw new ArgumentOutOfRangeException(nameof(c), c, "无效颜色值");
}
}
  • IsDefined方法必须慎用. 首先, IsDefined总是区分大小写;其次,IsDefined相当慢,因为它在内部使用了反射.

15.2 位标志

  • 示例代码:
        [Flags]
public enum FileAttributes
{
ReadOnly = 1,
Hidden = 2,
System = 4,
Directory = 16,
......
} static void Main(string[] args)
{
//判断文件是否隐藏
String file = Assembly.GetEntryAssembly().Location;
FileAttributes attributes = File.GetAttributes(file);
Console.WriteLine("Is {0} hidden? {1}", file, (attributes & FileAttributes.Hidden) != 0); //使用 HasFlag 方法(不推荐)
Console.WriteLine("Is {0} hidden? {1}", file, attributes.HasFlag(FileAttributes.Hidden)); //设置只读和隐藏特性
File.SetAttributes(file, FileAttributes.ReadOnly | FileAttributes.Hidden);
}
  • 避免使用 HasFlag,因为会装箱.
  • 永远不要对位标志枚举类型使用 IsDefined 方法. 因为无论传入数字或字符串,都只能进行简单匹配,通常会返回False.

15.3 向枚举类型添加方法

  • 本身不能添加方法,但是可通过"扩展方法"实现
        // flags 中是否包含 flagToTest
public static bool IsSet(this FileAttributes flags, FileAttributes flagToTest)
{
if (flagToTest == 0)
throw new ArgumentOutOfRangeException(nameof(flagToTest), "Value must not be 0");
return (flags & flagToTest) == flagToTest;
} // flags 中是否不包含 flagToTest
public static bool IsClear(this FileAttributes flags, FileAttributes flagToTest)
{
if (flagToTest == 0)
throw new ArgumentOutOfRangeException(nameof(flagToTest), "Value must not be 0");
return !IsSet(flags, flagToTest);
} // flags 中是否包含 testFlags 中的任何一个位标志
public static bool AnyFlagsSet(this FileAttributes flags, FileAttributes testFlags)
{
return (flags & testFlags) != 0;
} //将 setFlags 中包含的位标志,添加到 flags 中
public static FileAttributes Set(this FileAttributes flags, FileAttributes setFlags)
{
return flags | setFlags;
} //从 flags 中清除 指定的位标志(clearFlags)
public static FileAttributes Clear(this FileAttributes flags, FileAttributes clearFlags)
{
return flags & ~clearFlags;
} //遍历 flags 中包含的位标志
public static void ForEach(this FileAttributes flags, Action<FileAttributes> processFlag)
{
if (processFlag == null) throw new ArgumentNullException(nameof(processFlag));
for (UInt32 bit = 1; bit != 0; bit <<= 1)
{
UInt32 temp = ((UInt32)flags) & bit;
if (temp != 0) processFlag((FileAttributes)temp);
}
}

返回目录

<NET CLR via c# 第4版>笔记 第15章 枚举类型和位标志的更多相关文章

  1. 重温CLR(十一) 枚举类型、位标志和数组

    枚举类型 枚举类型(enumerated types)定义了一组"符号名称/值"配对.例如,以下Color类型定义了一组符号,每个符号都标识一种颜色: internal enum ...

  2. <NET CLR via c# 第4版>笔记 第18章 定制特性

    18.1 使用定制特性 FCL 中的几个常用定制特性. DllImport 特性应用于方法,告诉 CLR 该方法的实现位于指定 DLL 的非托管代码中. Serializable 特性应用于类型,告诉 ...

  3. <NET CLR via c# 第4版>笔记 第12章 泛型

    泛型优势: 源代码保护 使用泛型算法的开发人员不需要访问算法的源代码.(使用c++模板的泛型技术,算法的源代码必须提供给使用算法的用户) 类型安全 向List<DateTime>实例添加一 ...

  4. <NET CLR via c# 第4版>笔记 第7章 常量和字段

    7.1 常量 常量 是值从不变化的符号.定义常量符号时,它的值必须能够在编译时确定. 只能定义编译器识别的基元类型的常量,如果是非基元类型,需把值设为null. 常量的值直接嵌入代码,所以不能获取常量 ...

  5. <NET CLR via c# 第4版>笔记 第8章 方法

    8.1 实例构造器和类(引用类型) 构造引用类型的对象时,在调用类型的实例构造器之前,为对象分配的内存总是先被归零 .没有被构造器显式重写的所有字段都保证获得 0 或 null 值. 构造器不能被继承 ...

  6. <NET CLR via c# 第4版>笔记 第9章 参数

    9.1 可选参数和命名参数 class Program { private static int s_n = 0; private static void M(int x = 9, string s ...

  7. <NET CLR via c# 第4版>笔记 第19章 可空值类型

    System.Nullable<T> 是结构. 19.1 C# 对可空值类型的支持 C# 允许用问号表示法来声明可空值类型,如: Int32? x = 5; Int32? y = null ...

  8. <NET CLR via c# 第4版>笔记 第17章 委托

    17.1 初识委托 .net 通过委托来提供回调函数机制. 委托确保回调方法是类型安全的. 委托允许顺序调用多个方法. 17.2 用委托回调静态方法 将方法绑定到委托时,C# 和 CLR 都允许引用类 ...

  9. <NET CLR via c# 第4版>笔记 第16章 数组

    //创建一个一维数组 int[] myIntegers; //声明一个数组引用 myIntegers = new int[100]; //创建含有100个int的数组 //创建一个二维数组 doubl ...

随机推荐

  1. ActiveMQ 集群配置 高可用

    自从activemq5.9.0开始,activemq的集群实现方式取消了传统的Pure Master Slave方式,增加了基于zookeeper+leveldb的实现方式,其他两种方式:目录共享和数 ...

  2. Git项目创建与提交

    创建Git密钥: 1.生成密钥: 右键–>Git Bash Here:先输入ssh-keygen –t rsa –C "邮箱地址",注意ssh-keygen之间是没有空格的, ...

  3. Codeforces Round #542 [Alex Lopashev Thanks-Round] (Div. 1)

    A - Toy Train 很显然,一个站有多少个糖,那么就要从这个点运多少次.设第i个点有\(a_i\)个糖,那么就要转\(a_i-1\)圈,然后再走一段.很显然最后一段越小越好. 然后枚举起点后, ...

  4. 网页图片提取助手(支持背景图、选择dom范围)

    网页图片提取助手(支持背景图.选择dom范围) 网页图片下载工具.网页图片批量保存. 使用场景: 作为web前端开发首——学习小生的你我,仿学在线页面是常有的事,但是一些在线资源,比如图片,图片有im ...

  5. Python操作Rabbit MQ的5种模式

    python版本:   2.7.14 一 消息生产者代码: # -*- coding: utf-8 -*- import json import pika import urllib import u ...

  6. Python day21模块介绍4(logging模块,configparser模块)

    1.日志等级从上往下依次降低 logging.basicConfig(#日志报错打印的基础配置 level=logging.DEBUG, filename="logger.log" ...

  7. 算法笔记--2-sat

    强连通分量的应用,详见<挑战程序设计>P324 例题1:HDU Peaceful Commission 思路:强连通分量分解,看有没有两个同一个国家的代表在一个强连通分量里,如果有,就是N ...

  8. Codeforces 580A - Kefa and First Steps

    580A - Kefa and First Steps 思路:dp dp[i]表示包括前i个元素中a[i]在内的最大增序列. 代码: #include<bits/stdc++.h> usi ...

  9. _proto_和prototype区别

    推荐一篇阅读:http://cometosay.com/2016/08/31/js-proto.html es中创建对象的方法 (1)对象字面量的方式 (2)new 的方式 (3)ES5中的`Obje ...

  10. angular5 ng-bootstrap和ngx-bootstrap区别

    https://angular.cn/resources ngx-bootstrap 安装: npm install ngx-bootstrap --save 再引入css <link href ...