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. 卸载vs2017

    卸载enterprise版本 Microsoft.FSharp.SDK.Core卸载失败Package 'Microsoft.FSharp.SDK.Core,version=15.7.20180605 ...

  2. Java ArrayDeque源码剖析

    ArrayDeque 本文github地址 前言 Java里有一个叫做Stack的类,却没有叫做Queue的类(它是个接口名字).当需要使用栈时,Java已不推荐使用Stack,而是推荐使用更高效的A ...

  3. each遍历小结

    JQ中的遍历函数 (逐个加工函数) 格式: $(‘.box p’).each(function(index,element){ })也可以写成 $.each(‘.box p’,function(ind ...

  4. [异常记录-12]Web Deploy部署:未能连接到远程计算机,请确保在远程计算机上安装了 Web Deploy 并启动了所需的进程("Web Management Service")

    Web Deploy 安装 请参考:图文详解远程部署ASP.NET MVC 5项目 如此安装后还不行,  可以在卸载后重新安装 Web Deploy 时,不要选那个经典还是典型的安装选项,选自定义安装 ...

  5. FAILED Selenium2Library

    FAILED Selenium2Library Importing test library 'Selenium2Library' failed: ImportError: cannot import ...

  6. Myeclipse下配置svn

    转载高鑫的..嘻嘻.. MyEclipse安装配置SVN 2013.10.15 No Comments 67 Views 配置之前请先关闭MyEclipse,OK开始了 1.解压site-1.6.18 ...

  7. Codeforces 899E - Segments Removal

    899E - Segments Removal 思路:priority_queue+pair 代码: #include<bits/stdc++.h> using namespace std ...

  8. mac 下安装mongodb

    转载自https://segmentfault.com/a/1190000002547229 概念 MongoDB 是一个跨平台的,面向文档的数据库,提供高性能,高可用性和可扩展性方便. MongoD ...

  9. 筛选datatable

    当从数据库里取出一些数据,然后要对数据进行整合,很容易就会想到: DataTable dt = new DataTable();//假设dt是由"SELECT C1,C2,C3 FROM T ...

  10. English trip -- VC(情景课)5 B Places around town 城市设施

    Vocabulary focus 核心词汇  drugstore  药店:    pill  n. 药丸:弹丸,子弹:口服避孕药         medicine  n. 药:医学:内科:巫术 hos ...