<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 ...
随机推荐
- C#学习笔记(七):结构体、数组、冒泡排序和调试
结构体 结构体不能重写默认无参构造函数 一位数组 using System; using System.Collections.Generic; using System.Linq; using Sy ...
- 《C语言程序设计》指针篇<二>
通过指针引用多维数组 如何理解二维数组元素的地址? 要知道,这本书用了整整两页的内容来讲解这方面的知识,从这里足以看出来理解通过指针来引用二维数组是一件比较麻烦的事情,但是我认为理解并不难. 什么是二 ...
- codeforces 351 div2 C. Bear and Colors 暴力
C. Bear and Colors time limit per test 2 seconds memory limit per test 256 megabytes input standard ...
- java23种设计模式之一: 策略模式
由于最近在研究学习设计模式,我会用自己的理解方式来表述对设计模式的学习和认识,通过最常用.好记的案例来记住和使用设计模式,希望对设计代码方面有所提高和改进. 一.应用背景 在软件开发中常常遇到 ...
- Python day17 模块介绍1(time,random)
module模块和包的介绍(略掉了) 常用模块 # time模块 import time print(time.time())#时间戳,在1970年开始到现在一共多少秒 print(time.gmti ...
- Codeforces 431C - k-Tree
431C - k-Tree 思路:dp. dp[i][j][s] 如果s为1,表示第i层长度为j且至少包含一段>=d的距离的路径数 如果s为0,表示第i层长度为j且不包含一段>=d的距离的 ...
- Java注解的使用,类似于C#的Attribute
1.定义注解,代码如下: import java.lang.annotation.*; /** * 定义注解类,用于注解某个类或方法 * * @author Administrator * */ @T ...
- C#复制数据到剪切板
C#复制数据到剪切板 1. 复制固定的数据到剪切板 Clipboard.SetText("123456"); 于是123456就已经复制到剪切板中了,无论在任何地方粘贴都会出现‘1 ...
- 【转】ArcGIS API for Silverlight/WPF 2.1学习笔记(二)
五.Graphics layer 1.新增Graphics layer Graphics layer用于显示用户自定义绘制的点.线.面图形.使用时确保xaml文件中Graphics layer定义 ...
- Vue.js教程--基础2(事件处理 表单输入绑定
事件处理 表单输入绑定 事件处理 监听v-on 监听 DOM 事件,并在触发时运行一些 JavaScript 代码. 可以在v-on:click=''加内联语句. 有时也需要在内联语句处理器中访问原始 ...