C#学习笔记(1)基本语法

1.简介:

  • 与C/C++区别:
    • 指针只能用于不安全模式,大多数对象访问采用安全的引用实现
    • 对象不能被显式释放,当不存在被引用时通过垃圾回收器回收
    • 只允许单一继承,但是一个类可以实现多个接口
    • 比C++更加类型安全,默认的安全转换时隐含转换
    • 数组声明语法不哦那个,(int[] a = new int[5])
    • 枚举位于其所在的名字空间中
    • C#中没有模板,但是有泛型
    • 属性支持,使用类似访问成员的方式调用
    • 完整的反射支持
  • 优点:
    • 完整的.NET库
    • 可转移
    • 更先进的语法体系
  • 缺点:
    • 跨平台能力差
    • 不适合初学者

2.程序结构:

  • 结构
    • 命名空间声明
    • 一个class
    • class方法
    • class属性
    • 一个main方法
    • 语句&表达式
  • 注意点:
    • C#是大小写敏感的
    • 所有的语句和表达式必须以分号结尾
    • 程序的执行从Main方法开始
    • 与Java不同,文件名可以不同于类的名称

3.基本语法:

  • using关键字:用于再程序中包含命名空间
  • class关键字:用于声明一个类
  • 注释:单行//;多行/**/
  • 成员变量:类的属性或数据成员,用于存储数据
  • 成员函数:执行指定任务的语句
  • 标识符:用于识别类、变量、函数或任何其他用户定义的项目,必须以字母开头,不可以包含除_外的其他嵌入空格或符号,不能是C#关键字
  • C#关键字:C#预定义保留字

4.数据类型:

  • 值类型:从类 System.ValueType 中派生
    • 需要得到一个类型或变量的准确尺寸,可以采用sizeof(type),得到字节数据
  • 引用类型:不包含存储再变量中的实际数据,但包含对变量的引用,指的是一个内存位置
    • 内置引用类型
      • 对象类型:System.Object 类的别名,可以被分配任何其他类型,类型检查在编译时发生
        • 装箱:一个值类型转换为对象类型
        • 拆箱:对象类型转换为值类型
        • object <variable_name> = value
      • 动态类型:与对象类型相似,类型检查在运行时发生
        • dynamic <variable_name> = value
      • 字符串类型:System.String 类的别名,从object类派生。
        • string str = @"C:\Windows";
        • string str = "C:\\Windows";
        • @(称作"逐字字符串")将转义字符(\)当作普通字符对待,@字符串中可以任意换行,换行符及缩进空格都计算在字符串长度之内
    • 用户引用类型:class、interface、delegate
  • 指针类型:存储另一种类型的内存地址,与C++中的指针有相同功能
    • type* identifier;

5.类型转换:

  • 隐式类型转换:C#默认的以安全方式进行转换(小数-大数,派生类-基类)
  • 显式类型转换:通过用户使用预定义的函数进行转换,需要强制转换运算符
  • (type)var
  • Totype(ToString、ToInt32等)

6.C#变量:

  • 变量类型:
    • 整数类型:sbyte、byte、short、ushort、int、uint、long、ulong、char
    • 浮点型
    • 十进制类型
    • 布尔类型
    • 空类型
  • 变量定义:<data_type> <variable_list>;
  • 变量初始化:<data_type> <variable_name> = value;
  • 接受用户的值:Console.ReadLine() 只能接受string类型数据但可使用内置类型转换函数转换为其他类型
  • 左值和右值:
    • lvalue:可以出现在赋值语句的左边或右边
    • rvalue:只能出现在赋值语句的右边

7.常量:

  • 整数常量:
    • 前缀指定基数:0x 或 0X 表示十六进制,0 表示八进制,没有前缀则表示十进制
    • 后缀,可以是 U 和 L 的组合,U 和 L 分别表示 unsigned 和 long。后缀大小写不敏感,多个后缀以任意顺序进行组合
  • 浮点常量:
    • 小数形式:使用小数形式表示时,必须包含小数点、指数或同时包含两者。
    • 指数形式:使用指数形式表示时,必须包含整数部分、小数部分或同时包含两者。有符号的指数是用 e 或 E 表示的。
  • 字符常量:括在单引号内,可以是一个普通字符、一个转义序列或一个通用字符
  • 字符串常量:字符常量是括在双引号 "" 里,或者是括在 @"" 里
  • 定义常量:const <data_type> <constant_name> = value;

8.运算符:

  • 算术运算符:与C++类似
  • 关系运算符:与C++类似
  • 逻辑运算符:逻辑与&&、逻辑或||、逻辑非!
  • 位运算符:位与&、位或|、位异或^、位翻转~、位左移<<、位右移>>
  • 赋值运算符:与C++类似
  • 杂项运算符:
    • 运算符描述实例 sizeof()返回数据类型的大小。
    • typeof()返回 class 的类型
    • &返回变量的地址。
    • *变量的指针。
    • ? :条件表达式 如果条件为真 ? 则为 X : 否则为 Y
    • is判断对象是否为某一类型:If( Ford is Car)
    • as强制转换,即使转换失败也不会抛出异常:Object obj = new StringReader("Hello"); StringReader r = obj as StringReader;
  • 运算符优先级:与C++类似

9.判断:

  • if else语句
  • switch语句
  • ?:语句

10.循环:

  • 类型:
    • while
    • for/foreach:foreach一般只能用于遍历读取,不能更改引用变量
    • do while
  • 循环控制语句:
    • break语句:
      • 终止循环
      • 终止switch语句中的一个case
    • continue语句:跳过当前循环中的代码,强迫开始下一次循环
      • 对于 for 循环,continue 语句会导致执行条件测试和循环增量部分。
      • 对于 while 和 do...while 循环,continue 语句会导致程序控制回到条件测试上。
  • 无限循环:使用 for(;;) 结构来表示一个无限循环(空条件被认为是真)

11.方法:

  • 定义方法:
    • 定义语法:<Access Specifier> <Return Type> <Method Name>(Parameter List){ Method Body }
    • Access Specifier:访问修饰符,决定变量或方法对于另一个类的可见性
    • return type:返回类型是方法返回的值的数据类型。如果不返回任何值,则为 void
    • method name:方法名称,唯一标识符,大小写敏感,首字母大写
    • parameter list:参数列表,可选
    • method body:方法主体,包含了完成任务所需的指令集
  • 调用方法
    • 方法名调用:可以从另一个类中调用其他类的公有方法
    • 递归调用:一个方法可以自我调用
    • 参数传递
      • 值参数:
        • 默认方式。
        • 在这种方式下,当调用一个方法时,会为每个值参数创建一个新的存储位置。
        • 实际参数的值会复制给形参,实参和形参使用的是两个不同内存中的值,保证了实参数据的安全
      • 引用参数:
        • 引用参数是一个对变量的内存位置的引用,不会为这些参数创建一个新的存储位置。
        • 引用参数表示与提供给方法的实际参数具有相同的内存位置。使用 ref 关键字声明引用参数(定义和调用方法时都需要加上ref关键字)
      • 输出参数:
        • 输出参数会把方法输出的数据赋给自己,其他方面与引用参数相似。
        • 使用 out关键字声明输出参数

12.可空类型(Nullable):

  • 声明可空类型:< data_type> ? <variable_name> = null(value);
  • Null合并运算符(??):num3 = num1 ?? 5.34;
    • Null 合并运算符为类型转换定义了一个预设值,以防可空类型的值为 Null
    • 如果第一个操作数的值为 null,则运算符返回第二个操作数的值,否则返回第一个操作数的值

13.数组:

  • 声明数组:datatype[] arrayName;
  • 初始化数组:double[] balance = new double[10];
  • 赋值给数组:
    • 使用索引赋值:balance[0] = 4500.0;
    • 声明同时赋值:double[] balance = { 2340.0, 4523.69, 3421.0};
    • 初始化赋值:int [] marks = new int[5] { 99, 98, 92, 97, 95};
    • 赋值一个数组变量到另一个目标数组变量:int[] score = marks;(目标和源会指向相同的内存位置)
  • 访问数组元素:double salary = balance[9];

14.数组细节:

  • 多维数组:
    • 声明多维数组:string [,] names;
    • 初始化多维数组:int [,] a = int [3,4] = { {0, 1, 2, 3} , {4, 5, 6, 7} , {8, 9, 10, 11} };
    • 访问多维数组:int val = a[2,3];
  • 交错数组(数组的数组):
    • 声明交错数组(不会再内存中创建):int [][] scores;
    • 创建交错数组:int[][] scores = new int[5][]; for (int i = 0; i < scores.Length; i++) { scores[i] = new int[4]; }
    • 初始化交错数组:int[][] scores = new int[2][]{new int[]{92,93,94},new int[]{85,66,87,88}};
    • 访问交错数组:scores[i][j]
  • 传递数组给函数:
    • 通过指定不带索引的数组名称来给函数传递一个指向数组的指针(在函数内改变数组的值会导致原数组也改变)
    • 示例:double getAverage(int[] arr, int size) avg = app.getAverage(balance, 5 ) ;
  • 参数数组:通常用于传递未知数量的参数给函数
    • params关键字:public 返回类型 方法名称( params 类型名称[] 数组名称 )
    • 使用该方法可以传入非数组形式的多个参数,如app.AddElements(512, 720);
  • Array类:
    • 属性:
      • IsFixedSize:获取一个值,该值指示数组是否带有固定大小
      • IsReadOnly:获取一个值,该值指示数组是否只读
      • Length:获取一个 32 位整数,该值表示所有维度的数组中的元素总数
      • LongLength:获取一个 32 位整数,该值表示所有维度的数组中的元素总数
      • Rank:获取数组的秩(维度)
    • 方法:
      • Clear:根据元素的类型,设置数组中某个范围的元素为零、为 false 或者为 null
      • Copy(Array, Array, Int32):从数组的第一个元素开始复制某个范围的元素到另一个数组的第一个元素位置。长度由一个 32 位整数指定
      • CopyTo(Array, Int32):从当前的一维数组中复制所有的元素到一个指定的一维数组的指定索引位置。索引由一个 32 位整数指定
      • GetLength:获取一个 32 位整数,该值表示指定维度的数组中的元素总数
      • GetLongLength:获取一个 64 位整数,该值表示指定维度的数组中的元素总数
      • GetLowerBound:获取数组中指定维度的下界
      • GetType:获取当前实例的类型。从对象(Object)继承
      • GetUpperBound:获取数组中指定维度的上界
      • GetValue(Int32):获取一维数组中指定位置的值。索引由一个 32 位整数指定
      • IndexOf(Array, Object):搜索指定的对象,返回整个一维数组中第一次出现的索引
      • Reverse(Array):逆转整个一维数组中元素的顺序
      • SetValue(Object, Int32):给一维数组中指定位置的元素设置值。索引由一个 32 位整数指定
      • Sort(Array):使用数组的每个元素的 IComparable 实现来排序整个一维数组中的元素
      • ToString:返回一个表示当前对象的字符串。从对象(Object)继承

15.字符串(String):

  • 创建String对象:
    • 通过给 String 变量指定一个字符串
    • 通过使用 String 类构造函数
    • 通过使用字符串串联运算符( + )
    • 通过检索属性或调用一个返回字符串的方法
    • 通过格式化方法来转换一个值或对象为它的字符串表示形式
  • String类属性:
    • chars:在当前 String 对象中获取 Char 对象的指定位置
    • Length:在当前的 String 对象中获取字符数
  • String类方法:
    • public static int Compare( string strA, string strB ) :比较两个指定的 string 对象,并返回一个表示它们在排列顺序中相对位置的整数。该方法区分大小写
    • public static int Compare( string strA, string strB, bool ignoreCase ) :比较两个指定的 string 对象,并返回一个表示它们在排列顺序中相对位置的整数。但是,如果布尔参数为真时,该方法不区分大小写
    • public static string Concat( string str0, string str1 ) :连接两个 string 对象
    • public static string Concat( string str0, string str1, string str2 ) :连接三个 string 对象
    • public static string Concat( string str0, string str1, string str2, string str3 ) :连接四个 string 对象
    • public bool Contains( string value ) :返回一个表示指定 string 对象是否出现在字符串中的值
    • public static string Copy( string str ) :创建一个与指定字符串具有相同值的新的 String 对象
    • public void CopyTo( int sourceIndex, char[] destination, int destinationIndex, int count ) :从 string 对象的指定位置开始复制指定数量的字符到 Unicode 字符数组中的指定位置
    • public bool EndsWith( string value ) :判断 string 对象的结尾是否匹配指定的字符串
    • public bool Equals( string value ) :判断当前的 string 对象是否与指定的 string 对象具有相同的值
    • public static bool Equals( string a, string b ) :判断两个指定的 string 对象是否具有相同的值
    • public static string Format( string format, Object arg0 ) :把指定字符串中一个或多个格式项替换为指定对象的字符串表示形式
    • public int IndexOf( char value ):返回指定 Unicode 字符在当前字符串中第一次出现的索引,索引从 0 开始
    • public int IndexOf( string value ) :返回指定字符串在该实例中第一次出现的索引,索引从 0 开始
    • public int IndexOf( char value, int startIndex ) :返回指定 Unicode 字符从该字符串中指定字符位置开始搜索第一次出现的索引,索引从 0 开始
    • public int IndexOf( string value, int startIndex ) :返回指定字符串从该实例中指定字符位置开始搜索第一次出现的索引,索引从 0 开始
    • public int IndexOfAny( char[] anyOf ) :返回某一个指定的 Unicode 字符数组中任意字符在该实例中第一次出现的索引,索引从 0 开始
    • public int IndexOfAny( char[] anyOf, int startIndex ) :返回某一个指定的 Unicode 字符数组中任意字符从该实例中指定字符位置开始搜索第一次出现的索引,索引从 0 开始
    • public string Insert( int startIndex, string value ) :返回一个新的字符串,其中,指定的字符串被插入在当前 string 对象的指定索引位置
    • public static bool IsNullOrEmpty( string value ):指示指定的字符串是否为 null 或者是否为一个空的字符串
    • public static string Join( string separator, params string[] value ):连接一个字符串数组中的所有元素,使用指定的分隔符分隔每个元素
    • public static string Join( string separator, string[] value, int startIndex, int count )
    • public int LastIndexOf( char value ) :返回指定 Unicode 字符在当前 string 对象中最后一次出现的索引位置,索引从 0 开始
    • public int LastIndexOf( string value ) :返回指定字符串在当前 string 对象中最后一次出现的索引位置,索引从 0 开始
    • public string Remove( int startIndex ):移除当前实例中的所有字符,从指定位置开始,一直到最后一个位置为止,并返回字符串
    • public string Remove( int startIndex, int count ) :从当前字符串的指定位置开始移除指定数量的字符,并返回字符串
    • public string Replace( char oldChar, char newChar ):把当前 string 对象中,所有指定的 Unicode 字符替换为另一个指定的 Unicode 字符,并返回新的字符串
    • public string Replace( string oldValue, string newValue ) :把当前 string 对象中,所有指定的字符串替换为另一个指定的字符串,并返回新的字符串
    • public string[] Split( params char[] separator ) :返回一个字符串数组,包含当前的 string 对象中的子字符串,子字符串是使用指定的 Unicode 字符数组中的元素进行分隔的
    • public string[] Split( char[] separator, int count ) :返回一个字符串数组,包含当前的 string 对象中的子字符串,子字符串是使用指定的 Unicode 字符数组中的元素进行分隔的。int 参数指定要返回的子字符串的最大数目
    • public bool StartsWith( string value ) :判断字符串实例的开头是否匹配指定的字符串
    • public char[] ToCharArray():返回一个带有当前 string 对象中所有字符的 Unicode 字符数组
    • public char[] ToCharArray( int startIndex, int length ):返回一个带有当前 string 对象中所有字符的 Unicode 字符数组,从指定的索引开始,直到指定的长度为止
    • public string ToLower():把字符串转换为小写并返回
    • public string ToUpper():把字符串转换为大写并返回
    • public string Trim():移除当前 String 对象中的所有前导空白字符和后置空白字符

16.结构(Struct):值类型数据结构,使得一个单一变量可以存储各种数据类型的相关数据

  • 定义结构:struct Books{ public string title; public string author; public string subject; public int book_id; };
  • 结构特点:
    • 结构可带有方法、字段、索引、属性、运算符方法和事件。
    • 结构可定义构造函数,但不能定义析构函数。但是,您不能为结构定义默认的构造函数。默认的构造函数是自动定义的,且不能被改变。
    • 与类不同,结构不能继承其他的结构或类。
    • 结构不能作为其他结构或类的基础结构。
    • 结构可实现一个或多个接口。
    • 结构成员不能指定为 abstract、virtual 或 protected。
    • 当您使用 New 操作符创建一个结构对象时,会调用适当的构造函数来创建结构。与类不同,结构可以不使用 New 操作符即可被实例化。
    • 如果不使用 New 操作符,只有在所有的字段都被初始化之后,字段才被赋值,对象才被使用。
  • 与类的不同:
    • 类是引用类型,结构是值类型。
    • 结构不支持继承。
    • 结构不能声明默认的构造函数。

17.枚举(Enum):

  • 声明枚举变量:enum <enum_name> { enumeration list };
  • 示例:enum Days { Sun, Mon, tue, Wed, thu, Fri, Sat }; int WeekdayStart = (int)Days.Mon (=1)
  • 枚举列表中的每个符号代表一个整数值,一个比它前面的符号大的整数值。默认情况下,第一个枚举符号的值是 0

18.类(Class):

  • 类的定义:
    • <access specifier> class class_name
       { 
          // member 
          variables <access specifier> <data type> variable1; 
          <access specifier> <data type> variable2; 
          ... 
          <access specifier> <data type> variableN; 
      
          // member methods 
          <access specifier> <return type> method1(parameter_list) 
          { 
              // method body 
          } 
          <access specifier> <return type> method2(parameter_list) 
          { 
              // method body 
          } 
          
          ... 
          
          <access specifier> <return type> methodN(parameter_list) 
          { 
              // method body 
          } 
      }
    • 访问标识符 <access specifier> 指定了对类及其成员的访问规则。如果没有指定,则使用默认的访问标识符。类的默认访问标识符是 internal,成员的默认访问标识符是 private。
    • 数据类型 <data type> 指定了变量的类型,返回类型 <return type> 指定了返回的方法返回的数据类型。
    • 如果要访问类的成员,您要使用点(.)运算符。
    • 点运算符链接了对象的名称和成员的名称。
  • 成员函数和封装:
    • 成员函数是一个在类定义中有它的定义或原型的函数,就像其他变量一样。作为类的一个成员,它能在类的任何对象上操作,且能访问该对象的类的所有成员。
    • 成员变量是对象的属性(从设计角度),且它们保持私有来实现封装。这些变量只能使用公共成员函数来访问。
  • 构造函数:
    • 构造函数 是类的一个特殊的成员函数,当创建类的新对象时执行。构造函数的名称与类的名称完全相同,它没有任何返回类型。
    • 默认的构造函数没有任何参数。但是如果您需要一个带有参数的构造函数可以有参数,这种构造函数叫做参数化构造函数。
  • 析构函数:
    • 析构函数 是类的一个特殊的成员函数,当类的对象超出范围时执行,用于在结束程序(比如关闭文件、释放内存等)之前释放资源。析构函数不能继承或重载
    • 析构函数的名称是在类的名称前加上一个波浪形(~)作为前缀,它不返回值,也不带任何参数
  • 静态成员:
    • 使用 static 关键字把类成员定义为静态的。当我们声明一个类成员为静态时,意味着无论有多少个类的对象被创建,只会有一个该静态成员的副本
    • 静态变量用于定义常量,因为它们的值可以通过直接调用类而不需要创建类的实例来获取。静态变量可在成员函数或类的定义外部进行初始化。您也可以在类的定义内部初始化静态变量
    • 也可以把一个成员函数声明为 static。这样的函数只能访问静态变量。静态函数在对象被创建之前就已经存在

19.继承:允许我们根据一个类来定义另一个类

  • 基类和派生类:
    • 派生类只能有一个直接基类,但一个基类可以有多个直接派生类。继承是可以传递的。定义要从其他类派生的类时,派生类会隐式获得基类的所有成员(除了其构造函数和终结器)
    • 创建派生类:
      • <acess-specifier> class <base_class> { ... } 
        class <derived_class> : <base_class> { ... }
    • 基类初始化:
      • 父类对象应在子类对象创建之前被创建,可以在成员初始化列表中进行父类的初始化
      • 示例:
         public Tabletop(double l, double w) : base(l, w) { }
      • 在子类(派生类)中用 base 代表父类(基类)
    • 多重继承:C#不支持多重继承,但可以用接口来实现

20.多态性:

  • 静态多态性
    • 函数重载:可在同一个范围内对相同的函数名有多个定义。函数的定义必须彼此不同,可以是参数列表中的参数类型不同,也可以是参数个数不同。不能重载只有返回类型不同的函数声明
    • 运算符重载:见下一章
  • 动态多态性
    • 抽象类:
      • 使用关键字 abstract 创建抽象类,用于提供接口的部分类的实现
      • 抽象类包含抽象方法,抽象方法可被派生类实现
      • 抽象类不能被声明为 sealed(密封类)
      • 当一个派生类继承自该抽象类时,实现即完成(使用override关键字继承)
    • 虚方法:
      • 使用关键字 virtual 声明虚方法
      • 虚方法可以在不同的继承类中有不同的实现。
      • 对虚方法的调用是在运行时发生的
      • 当一个派生类继承自该虚方法时,实现即完成(使用override关键字继承)

21.运算符重载:

  • 重载运算符是具有特殊名称的函数,是通过关键字 operator 后跟运算符的符号来定义的。
  • 示例:
    public static Box operator+ (Box b, Box c) 
    { 
        Box box = new Box(); 
        box.length = b.length + c.length; 
        box.breadth = b.breadth + c.breadth; 
        box.height = b.height + c.height; 
        return box; 
    }
  • 重载运算符有返回类型和参数列表
  • 可重载运算符类型:一元运算符、二元元运算符、比较运算符

22.接口:

  • 接口定义了属性、方法和事件,这些都是接口的成员。接口只包含了成员的声明。成员的定义是派生类的责任。接口提供了派生类应遵循的标准结构
  • 声明接口:
    • 接口使用 interface 关键字声明,它与类的声明类似
    • 示例:
      public interface ITransactions 
      { 
          // 接口成员 
          void showTransaction(); 
          double getAmount(); 
      }
  • 抽象类在某种程度上与接口类似,但是,它们大多只是用在当只有少数方法由基类声明由派生类实现时。

23.命名空间:

  • 命名空间的设计目的是为了提供一种让一组名称与其他名称分隔开的方式。在一个命名空间中声明的类的名称与另一个命名空间中声明的相同的类的名称不冲突。
  • 定义命名空间:namespace namespace_name { // 代码声明 }
  • using 关键字:表明程序使用的是给定命名空间中的名称
  • 嵌套命名空间:命名空间可以被嵌套,即可以在一个命名空间内定义另一个命名空间

24.预处理指令:

  • 所有的预处理器指令都是以 # 开始。且在一行上,只有空白字符可以出现在预处理器指令之前。预处理器指令不是语句,所以它们不以分号(;)结束。
  • C# 编译器没有一个单独的预处理器,但是,指令被处理时就像是有一个单独的预处理器一样。在 C# 中,预处理器指令用于在条件编译中起作用。
  • #define 预处理器:
    • #define 预处理器指令创建符号常量:#define symbol
    • #define 允许您定义一个符号,这样,通过使用符号作为传递给 #if 指令的表达式,表达式将返回 true
  • 条件指令:
    • 条件指令语法:#if symbol [operator symbol]...
    • symbol 是要测试的符号名称,可以使用 true 和 false,或在符号前放置否定运算符
    • 条件指令用于在调试版本或编译指定配置时编译代码。
    • 一个以 #if 指令开始的条件指令,必须显示地以一个 #endif 指令终止。

25.正则表达式:正则表达式 是一种匹配输入文本的模式

  • 字符转义:正则表达式中的反斜杠字符(\)指示其后跟的字符是特殊字符,或应按原义解释该字符
  • 字符类:字符类与一组字符中的任何一个字符匹配
  • 定位点:定位点或原子零宽度断言会使匹配成功或失败,具体取决于字符串中的当前位置,但它们不会使引擎在字符串中前进或使用字符
  • 分组构造:分组构造描述了正则表达式的子表达式,通常用于捕获输入字符串的子字符串
  • 限定符
  • 反向引用构造
  • 备用构造
  • 替换
  • 杂项构造

26.异常处理:

  • 异常处理关键词:
    • try:一个 try 块标识了一个将被激活的特定的异常的代码块。后跟一个或多个 catch 块
    • catch:程序通过异常处理程序捕获异常。catch 关键字表示异常的捕获
    • finally:finally 块用于执行给定的语句,不管异常是否被抛出都会执行
    • throw:finally 块用于执行给定的语句,不管异常是否被抛出都会执行
  • 异常类:
    • System.IO.IOException:处理 I/O 错误。
    • System.IndexOutOfRangeException:处理当方法指向超出范围的数组索引时生成的错误。
    • System.ArrayTypeMismatchException:处理当数组类型不匹配时生成的错误。
    • System.NullReferenceException:处理当依从一个空对象时生成的错误。
    • System.DivideByZeroException:处理当除以零时生成的错误。
    • System.InvalidCastException:处理在类型转换期间生成的错误。
    • System.OutOfMemoryException:处理空闲内存不足生成的错误。
    • System.StackOverflowException:处理栈溢出生成的错误。
  • 异常处理:
    • C# 以 try 和 catch 块的形式提供了一种结构化的异常处理方案。使用这些块,把核心程序语句与错误处理语句分离开。
    • 示例:
      public void division(int num1, int num2) 
      { 
          try 
          { 
              result = num1 / num2; 
          } 
          catch (DivideByZeroException e) 
          { 
              Console.WriteLine("Exception caught: {0}", e); 
          } 
          finally 
          { 
              Console.WriteLine("Result: {0}", result); 
          } 
      }
  • 创建用户自定义异常:
    • 用户自定义的异常类是派生自 ApplicationException 类
    • public class TempIsZeroException: ApplicationException
      {
      
          public TempIsZeroException(string message): base(message)
      
          {
      
          }
      
      }
  • 抛出对象:如果异常是直接或间接派生自 System.Exception 类,您可以抛出一个对象。您可以在 catch 块中使用 throw 语句来抛出当前的对象

27.文件输入与输出:

  • 一个 文件 是一个存储在磁盘中带有指定名称和目录路径的数据集合。当打开文件进行读写时,它变成一个 流
  • 流是通过通信路径传递的字节序列。有两个主要的流:输入流 和 输出流。输入流用于从文件读取数据(读操作),输出流用于向文件写入数据(写操作)
  • I/O类:
    • BinaryReader:从二进制流读取原始数据。
    • BinaryWriter:以二进制格式写入原始数据。
    • BufferedStream:字节流的临时存储。
    • Directory:有助于操作目录结构。
    • DirectoryInfo:用于对目录执行操作。
    • DriveInfo:提供驱动器的信息。
    • File:有助于处理文件。
    • FileInfo:用于对文件执行操作。
    • FileStream:用于文件中任何位置的读写。
    • MemoryStream:用于随机访问存储在内存中的数据流。
    • Path:对路径信息执行操作。
    • StreamReader:用于从字节流中读取字符。
    • StreamWriter:用于向一个流中写入字符。
    • StringReader:用于读取字符串缓冲区。
    • StringWriter:用于写入字符串缓冲区。
  • FileStream类:
    • 创建FileStream类:FileStream <object_name> = new FileStream( <file_name>,<FileMode Enumerator>, <FileAccess Enumerator>, <FileShare Enumerator>);
    • FileMode:
      • Append:打开一个已有的文件,并将光标放置在文件的末尾。如果文件不存在,则创建文件。
      • Create:创建一个新的文件。如果文件已存在,则删除旧文件,然后创建新文件。
      • CreateNew:指定操作系统应创建一个新的文件。如果文件已存在,则抛出异常。
      • Open:打开一个已有的文件。如果文件不存在,则抛出异常。
      • OpenOrCreate:指定操作系统应打开一个已有的文件。如果文件不存在,则用指定的名称创建一个新的文件打开。
      • Truncate:打开一个已有的文件,文件一旦打开,就将被截断为零字节大小。然后我们可以向文件写入全新的数据,但是保留文件的初始创建日期。如果文件不存在,则抛出异常。
    • FileAccess:FileAccess 枚举的成员有:Read、ReadWrite 和 Write
    • FileShare:
      • Inheritable:允许文件句柄可由子进程继承。Win32 不直接支持此功能。
      • None:谢绝共享当前文件。文件关闭前,打开该文件的任何请求(由此进程或另一进程发出的请求)都将失败。
      • Read:允许随后打开文件读取。如果未指定此标志,则文件关闭前,任何打开该文件以进行读取的请求(由此进程或另一进程发出的请求)都将失败。但是,即使指定了此标志,仍可能需要附加权限才能够访问该文件。
      • ReadWrite:允许随后打开文件读取或写入。如果未指定此标志,则文件关闭前,任何打开该文件以进行读取或写入的请求(由此进程或另一进程发出)都将失败。但是,即使指定了此标志,仍可能需要附加权限才能够访问该文件。
      • Write:允许随后打开文件写入。如果未指定此标志,则文件关闭前,任何打开该文件以进行写入的请求(由此进程或另一进过程发出的请求)都将失败。但是,即使指定了此标志,仍可能需要附加权限才能够访问该文件。
      • Delete:允许随后删除文件

猜你喜欢

转载自blog.csdn.net/stringYY/article/details/82149093