C#学习笔记2
1. 可空类型(Nullable)
?:单问号用于对int,double,bool 等无法直接赋值为null的数据类型进行null赋值,意思是这个数据类型是NullAble类型的。
int? i = 3 等同于 Nullable<int> i = new Nullable<int>(3); int i; //默认值0 int? ii; //默认值null
??:双问号可用于判断一个变量在为null时返回一个指定的值。
用处:在处理数据库和其他可能未赋值的元素的数据类型时,将null赋值给数值类型或布尔类型的功能特别有用。
声明一个 nullable 类型(可空类型)的语法如下:
< data_type> ? <variable_name> = null;
例子:
using System; namespace CalculatorApplication { class Program { static void Main(string[] args) { int? num1 = null; int? num2 = 45; double? num3 = new double?(); double? num4 = 3.1415926; bool? boolval = new bool(); //显示 Console.WriteLine("显示可空类型的值:{0},{1},{2},{3}", num1, num2, num3, num4); Console.WriteLine("一个可空的布尔值:{0}", boolval); Console.ReadLine(); } } }
结果
显示可空类型的值: , 45, , 3.14157 一个可空的布尔值:
Null合并运算符(??)
Null 合并运算符定义可空类型和引用类型的默认值。并且可以执行隐式类型转换,如double?转换为double
例子:
using System; namespace CalculatorApplication { class Program { static void Main(string[] args) { double? num1 = null; double? num2 = 3.1415926; double num3; num3 = num1 ?? 5.34; //num1如果为空值则返回5.34 Console.WriteLine("num3 的值:{0}", num3); num3 = num2 ?? 5.44; Console.WriteLine("num3 的值:{0}", num3); Console.ReadLine(); } } }
结果:
num3 的值: 5.34 num3 的值: 3.14157
2. C#预处理命令
预处理指令指导编译器在实际编译开始之前对信息进行预处理。
#define预处理器指令创建符号常量。该命令只能在所有代码最前面。
语法如下:
#define symbol
例子:
#define PI using System; namespace PreprocessorDAppl { class Program { static void Main(string[] args) { #if(PI) Console.WriteLine("PI is define"); #else Console.WriteLine("PI is not define"); //在编译器里这里会变成灰色,不会被编译,即使有语法错误项目也能编译成功 #endif Console.ReadKey(); } } }
条件指令
可以使用#if指令来创建一个条件指令。条件指令用于测试符号是否为真。如果为真,编译器会执行 #if 和下一个指令之间的代码。
语法如下:
#if symbol [operator symbol]...
其中,symbol 是要测试的符号名称。您也可以使用 true 和 false,或在符号前放置否定运算符。
常见运算符有:
- ==(等于)
- !=(不等于)
- & (与)
- || (或)
一个以 #if 指令开始的条件指令,必须显示地以一个 #endif 指令终止。
注意#elif为正确写法,没有#else if
#define DEBUG #define VC_V10 using System; namespace TestClass { class Program { static void Main(string[] args) { #if (DEBUG && !VC_V10) werhtsds #elif (!DEBUG && VC_V10) adshahrha #elif (DEBUG && VC_V10) Console.WriteLine("DEBUG and VC_V10 are defined"); #else Console.WriteLine("DEBUG and VC_V10 are not defined"); #endif Console.ReadKey(); } } }
上面代码会运行成功,结果如下
DEBUG and VC_V10 are defined
预处理器指令的用途理解:
在程序调试和运行上有重要的作用。比如预处理器指令可以禁止编译器编译代码的某一部分,如果计划发布两个版本的代码,即基本版本和有更多功能的企业版本,就可以使用这些预处理器指令来控制。在编译软件的基本版本时,使用预处理器指令还可以禁止编译器编译于额外功能相关的代码。另外,在编写提供调试信息的代码时,也可以使用预处理器指令进行控制。总的来说和普通的控制语句(if等)功能类似,方便在于预处理器指令包含的未执行部分是不需要编译的。
3. C#特性
特性(Attribute)用于在程序运行时传递程序中各种元素(如类、方法、结构、枚举、组件等)的形为信息的声明性标签。可以通过使用特性项程序添加声明性信息。一个声明性标签通过放置在它所应用的元素前面的方括号([])来描述。
特性用于添加元数据。如编译器指令和注释、描述、方法、类等其他信息。.Net框架提供了两种类型的特性:预定义特性和自定义特性。
规定特性
语法:
[attribute(positional_parameters, name_parameter = value, ...)]
element
特性的名称和值事再方括号内规定的,放置在它所应用的元素之前。positional_parameters规定必须的信息,name_parameter贵姓可选的信息。
预定义特性
.Net框架提供了三种预定义特性:
- AttributeUsage
- Condotional
- Obsolete
AttributeUsage描述了如何使用一个自定义特性类。他古icing了特性可应用到的项目和类型。
该特性的语法如下:
[AttributeUsage( validon, AllowMultiple=allowmultiple, Inherited=inherited )]
- 参数validon规定特性可被方式的语言元素。他是枚举器AttributeTargets的值的组合。默认值时AttributeTargets.All。
- 参数Allowmultiple(可选的)为该特性的AllowMultiple属性(property)提供一个布尔值。如果为true,则该特性时多用的。默认值是false(单用的)。
- 参数inherited(可选的)为该特性的Inherited属性(property)提供一个布尔值。如果为true,则该特性可被派生类继承。默认值是false(不被继承)。
例如:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Constructor | AttributeTargets.Field | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = true)]
Conditional预定义特性标记了一个条件方法,其执行依赖于指定的预处理标识符。
它会引起方法调用的条件编译,取决于指定的值,比如 Debug 或 Trace。例如,当调试代码时显示变量的值。
语法如下:
[Conditional(
conditionalSymbol
)]
例如:
[Conditional("DEBUG")]