<NET CLR via c# 第4版>笔记 第15章 枚举类型和位标志
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章 枚举类型和位标志的更多相关文章
- 重温CLR(十一) 枚举类型、位标志和数组
枚举类型 枚举类型(enumerated types)定义了一组"符号名称/值"配对.例如,以下Color类型定义了一组符号,每个符号都标识一种颜色: internal enum ...
- <NET CLR via c# 第4版>笔记 第18章 定制特性
18.1 使用定制特性 FCL 中的几个常用定制特性. DllImport 特性应用于方法,告诉 CLR 该方法的实现位于指定 DLL 的非托管代码中. Serializable 特性应用于类型,告诉 ...
- <NET CLR via c# 第4版>笔记 第12章 泛型
泛型优势: 源代码保护 使用泛型算法的开发人员不需要访问算法的源代码.(使用c++模板的泛型技术,算法的源代码必须提供给使用算法的用户) 类型安全 向List<DateTime>实例添加一 ...
- <NET CLR via c# 第4版>笔记 第7章 常量和字段
7.1 常量 常量 是值从不变化的符号.定义常量符号时,它的值必须能够在编译时确定. 只能定义编译器识别的基元类型的常量,如果是非基元类型,需把值设为null. 常量的值直接嵌入代码,所以不能获取常量 ...
- <NET CLR via c# 第4版>笔记 第8章 方法
8.1 实例构造器和类(引用类型) 构造引用类型的对象时,在调用类型的实例构造器之前,为对象分配的内存总是先被归零 .没有被构造器显式重写的所有字段都保证获得 0 或 null 值. 构造器不能被继承 ...
- <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 ...
- <NET CLR via c# 第4版>笔记 第19章 可空值类型
System.Nullable<T> 是结构. 19.1 C# 对可空值类型的支持 C# 允许用问号表示法来声明可空值类型,如: Int32? x = 5; Int32? y = null ...
- <NET CLR via c# 第4版>笔记 第17章 委托
17.1 初识委托 .net 通过委托来提供回调函数机制. 委托确保回调方法是类型安全的. 委托允许顺序调用多个方法. 17.2 用委托回调静态方法 将方法绑定到委托时,C# 和 CLR 都允许引用类 ...
- <NET CLR via c# 第4版>笔记 第16章 数组
//创建一个一维数组 int[] myIntegers; //声明一个数组引用 myIntegers = new int[100]; //创建含有100个int的数组 //创建一个二维数组 doubl ...
随机推荐
- 命令模式(head first 设计模式5)
一.命令模式定义 命令大家都不会陌生,那么在开始命令模式之前,可以想象一下生活中的命令模式的特点: 如老板命令你完成一个OA项目是一个命令,接着看看其特点: 1.在上面的命令中,命令的执行者肯定是聪明 ...
- UVa 1602 网格动物(回溯)
https://vjudge.net/problem/UVA-1602 题意:计算n连通块不同形态的个数. 思路: 实在是不知道该怎么做好,感觉判重实在是太麻烦了. 判重就是判断所有格子位置是否都相同 ...
- React Native 的组件之底部导航栏 TabBarIOS(一)
import React,{Component}from 'react'; import { AppRegistry, StyleSheet, Text, View, TabBarIOS, } fro ...
- 精通移动app测试实战
- myEclipse 下配置多个Tomcat
1.进入perfomance 2. 进入server 右键点击configure server connector 3. 切换到 “Arguments” 面板,这里有 一个启动参数,就是修改一下路径 ...
- Centos修改系统语言
使用man page帮助时,发现居然是中文的,不过想想即便英语再水,也要逼着自己去适应.于是百度找了一下修改系统语言的方法. 首先使用 locale 命令查看当前的系统语言 然后修改时一般有两种方法, ...
- scrapy 也能爬取妹子图?
目录 前言 Media Pipeline 启用Media Pipeline 使用 ImgPipeline 抓取妹子图 瞎比比前言 我们在抓取数据的过程中,除了要抓取文本数据之外,当然也会有抓取图片的需 ...
- iOS Socket编程-C语言版(UDP)
. UDP Socket编程 先讲一讲UDP编程,因为比TCP要简单多了.首先,我们需要明白UDP是用户数据报协议,英文名为User Datagram Protocol,它是面向无连接的. 注意:So ...
- windows 启用ipv6(for XX-net)补充“Ping请求找不到主机”问题
ipv6.google.com 有点地方直接能启用,有的时候不行. 导致在xx - net 里无法启用ipv6 这样搞试试 netsh int ipv6 isatap set state enable ...
- 错误代码0x00000001,好多软件连不了网,求助~(WIN7/win8/win9/win10)
解决办法: 以管理员身份运行命令行,在弹出的窗口中运行如下命令: netsh winsock reset catalog netsh int ip reset reset.log hit 让被阻止了的 ...