命名空间、预处理器指令、正则表达式、异常处理、文件的输入和输出、特性

26.命名空间(Namespace)
    命名空间的设计目的是提供一种让一组名称与其他名称分隔开的方式。在一个命名空间中声明的类的名称与另一个命名空间中声明的相同的类的名称不冲突。
    定义命名空间:命名空间的定义是以关键字 namespace 开始,后跟命名空间的名称,如下所示
        namespace namespace_name
        {
            //...
        }
        为了调用支持命名空间版本的函数或变量,会把命名空间的名称置于前面,如下所示:
        namespace_name.item_name;
        实例:
        using System;
        namespace first_space
        {
        class namespace_cl
        {
            public void func()
            {
                Console.WriteLine("Inside first_space");
            }
        }
        }
        namespace second_space
        {
        class namespace_cl
        {
            public void func()
            {
                Console.WriteLine("Inside second_space");
            }
        }
        }   
        class TestClass
        {
        static void Main(string[] args)
        {
            first_space.namespace_cl fc = new first_space.namespace_cl();
            second_space.namespace_cl sc = new second_space.namespace_cl();
            fc.func();// Inside first_space
            sc.func();// Inside second_space
            Console.ReadKey();
        }
        }
    using关键字:using 关键字表明程序使用的是给定命名空间中的名称。例如使用 System命令空间,则可以 System.Console.WriteLine("test");  System.可省略
        使用using 命名空间指令,这样在使用时便无需添加命名空间名称。
    嵌套命名空间:命名空间可以签到,即在一个命名空间中定义另一个命名空间。语法如下:
        namespace 命名空间名称
        {
            namespace 命名空间名称2
            {
            }
        }
        可使用(.)运算符访问嵌套的命名空间的成员。
        实例:
        using System;
        using SomeNameSpace;
        using SomeNameSpace.Nested;
        
        namespace SomeNameSpace
        {
            public class MyClass 
            {
                static void Main() 
                {
                    Console.WriteLine("In SomeNameSpace");
                    Nested.NestedNameSpaceClass.SayHello();
                }
            }
        
            // 内嵌命名空间
            namespace Nested   
            {
                public class NestedNameSpaceClass 
                {
                    public static void SayHello() 
                    {
                        Console.WriteLine("In Nested");
                    }
                }
            }
        }
        
27.预处理器指令:在程序调试和运行上有重要作用。
    预处理器指令(Preprocessor Directives)指导编译器在实际编译开始之前对信息进行预处理。
    通过这些指令,可以控制编译器如何编译文件或编译哪些部分。常见的预处理器指令包括条件编译、宏定义等。
    所有的预处理器指令都是以 # 开始,且在一行上,只有空白字符可以出现在预处理器指令之前。一个预处理器指令必须是该行上的唯一指令。
    预处理器指令不是语句,所以它们不以分号 ; 结束。
    C# 编译器没有一个单独的预处理器,但是,指令被处理时就像是有一个单独的预处理器一样。
    在 C# 中,预处理器指令用于在条件编译中起作用。与 C 和 C++ 不同的是,它们不是用来创建宏。
    C#预处理指令列表:
        #defin  定义一个符号,可用于条件编译
        #undef    取消定义一个符号。
        #if    开始一个条件编译块,如果符号被定义则包含代码块。
        #elif    如果前面的 #if 或 #elif 条件不满足,且当前条件满足,则包含代码块。
        #else    如果前面的 #if 或 #elif 条件不满足,则包含代码块。
        #endif    结束一个条件编译块。
        #warning    生成编译器警告信息。
        #error    生成编译器错误信息。
        #region    标记一段代码区域,可以在IDE中折叠和展开这段代码,便于代码的组织和阅读。
        #endregion    结束一个代码区域。
        #line    更改编译器输出中的行号和文件名,可以用于调试或生成工具的代码。
        #pragma    用于给编译器发送特殊指令,例如禁用或恢复特定的警告。
        #nullable    控制可空性上下文和注释,允许启用或禁用对可空引用类型的编译器检查。
        实例:
        #define DEBUG
        #if DEBUG
            Console.WriteLine("Debug mode");
        #elif RELEASE
            Console.WriteLine("Release mode");
        #else
            Console.WriteLine("Other mode");
        #endif
        
        #warning This is a warning message
        #error This is an error message
        
        #region MyRegion
            // Your code here
        #endregion
        
        #line 100 "MyFile.cs"
            // The next line will be reported as line 100 in MyFile.cs
            Console.WriteLine("This is line 100");
        #line default
            // Line numbering returns to normal
        
        #pragma warning disable 414
            private int unusedVariable;
        #pragma warning restore 414
        
        #nullable enable
            string? nullableString = null;
        #nullable disable
    #defin和#undef预处理器
        #define 用于定义符号(通常用于条件编译),#undef 用于取消定义符号。
            #define DEBUG
            #undef RELEASE
        #define 允许您定义一个符号,这样,通过使用符号作为传递给 #if 指令的表达式,表达式将返回 true。它的语法如下:
            #define symbol
            实例:
            #define PI 
            using System;
            namespace PreprocessorDAppl
            {
            class Program
            {
                static void Main(string[] args)
                {
                    #if (PI)
                        Console.WriteLine("PI is defined");
                    #else
                        Console.WriteLine("PI is not defined");
                    #endif
                    Console.ReadKey();
                }
                //输出结果为:PI is defined
            }
            }
    条件指令:#if、#elif、#else、@endif
        #if 创建条件指令,件指令用于测试符号是否为真。如果为真,编译器会执行 #if 和下一个指令之间的代码。
        条件指令语法:#if symbol [operator symbol]...
        symbol表示要测试的符号名称,也可以使用true或false,或在符号前防止否定运算符
        常见运算符有:==、!=、&&、||
        一个#if指令开始的条件指令,必须显示地以一个#endif指令终止
        实例:
        #define DEBUG

        #if DEBUG
            Console.WriteLine("Debug mode");
        #elif RELEASE
            Console.WriteLine("Release mode");
        #else
            Console.WriteLine("Other mode");
        #endif
        条件指令的用法:
        #define DEBUG
        #define VC_V10
        using System;
        public class TestClass
        {
        public static void Main()
        {
        
            #if (DEBUG && !VC_V10)
                Console.WriteLine("DEBUG is defined");
            #elif (!DEBUG && VC_V10)
                Console.WriteLine("VC_V10 is defined");
            #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
        }
        }
    #warning 和 #error
        #warning 用于生成编译器警告,#error 用于生成编译器错误。
        实例:
            #warning This is a warning message
            #error This is an error message
    #region 和 #endregion:用于代码折叠,使代码更加可读
        实例:
        #region MyRegion
    // Your code here
        #endregion
    #line 用于更改文件行号和文件名的编译器输出。
        实例:
        #line 100 "MyFile.cs"
        // The next line will be reported as line 100 in MyFile.cs
        Console.WriteLine("This is line 100");
        #line default  //恢复默认行号
        // Line numbering returns to normal
    #pragma:用于向编译器发送特殊指令。最常见的用法是禁用特定的警告。
        实例:
        #pragma warning disable 414
            private int unusedVariable;
        #pragma warning restore 414
        可以抑制或还原特定的编译警告,与命令行选项不同,#pragma 指令可以在类或方法级别执行,对抑制警告的内容和抑制的时间进行更精细的控制。
        #pragma warning disable 169    // 取消编号 169 的警告(字段未使用的警告)
        public class MyClass
        {
            int neverUsedField;       // 编译整个 MyClass 类时不会发出警告
        }
        #pragma warning restore 169   // 恢复编号 169 的警告
    使用预处理器指令的注意事项:
        提高代码可读性:使用#region可以帮助分隔代码块,提高代码的组织性。
        条件编译:通过#if等指令可以在开发和生产环境中编译不同的代码,方便调试和发布。
        警告和错误:通过#warning和#error可以在编译时提示开发人员注意特定问题。
    通过控制预处理器指令,可以更好地控制代码的编译过程,提高代码的灵活性和可维护性质。

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

    .Net 框架提供了允许这种匹配的正则表达式引擎。

    模式由一个或多个字符、运算符和结构组成。
    定义正则表达式:用于定义正则表达式的各种类别的字符、运算符和结构。
        字符转义、字符类、定位点、分组构造、限定符、反向引用构造、备用构造、替换、杂项构造
    字符转义:正则表达式中的反斜杠字符(\)指示其后跟的字符是特殊字符,或应按原义解释该字符。
        \a    与报警 (bell) 符 \u0007 匹配。
        \b    在字符类中,与退格键 \u0008 匹配。
        \t    与制表符 \u0009 匹配。
        \r    与回车符 \u000D 匹配。
        \v    与垂直制表符 \u000B 匹配。    
        \f    与换页符 \u000C 匹配。    
        \n    与换行符 \u000A 匹配。    
        \e    与转义符 \u001B 匹配
    字符类:与一组字符的任何一个字符匹配
        \w    与任何单词字符匹配。    
        \W    与任何非单词字符匹配。    
        \s    与任何空白字符匹配。    
        \S    与任何非空白字符匹配。    
        \d    与任何十进制数字匹配。    
        \D    匹配不是十进制数的任意字符。
    定位点:定位点或原子零宽度断言会使匹配成功或失败,具体取决于字符串中的当前位置,但它们不会使引擎在字符串中前进或使用字符。
        ^    匹配必须从字符串或一行的开头开始。    
        $    匹配必须出现在字符串的末尾或出现在行或字符串末尾的 \n 之前。    
        \A    匹配必须出现在字符串的开头。    
        \Z    匹配必须出现在字符串的末尾或出现在字符串末尾的 \n 之前。    
        \z    匹配必须出现在字符串的末尾。    
        \G    匹配必须出现在上一个匹配结束的地方。    
        \b    匹配一个单词边界,也就是指单词和空格间的位置。    er\b    匹配"never"中的"er",但不能匹配"verb"中的"er"。
        \B    匹配非单词边界。
    分组构造:分组构造描述了正则表达式的子表达式,通常用于捕获输入字符串的子字符串。
    限定符:限定符指定在输入字符串中必须存在上一个元素(可以是字符、组或字符类)的多少个实例才能出现匹配项。
        *    匹配上一个元素零次或多次。    
        +    匹配上一个元素一次或多次。    
        ?    匹配上一个元素零次或一次。    
        { n }    匹配上一个元素恰好 n 次。
        { n ,}    匹配上一个元素至少 n 次。    
        { n , m }    匹配上一个元素至少 n 次,但不多于 m 次。    
        *?    匹配上一个元素零次或多次,但次数尽可能少。    
        +?    匹配上一个元素一次或多次,但次数尽可能少。    
        ??    匹配上一个元素零次或一次,但次数尽可能少。    
        { n }?    匹配前导元素恰好 n 次。
        { n ,}?    匹配上一个元素至少 n 次,但次数尽可能少。    
        { n , m }?    匹配上一个元素的次数介于 n 和 m 之间,但次数尽可能少。
    反向引用构造:反向引用允许在同一正则表达式中随后标识以前匹配的子表达式。
    备用构造:备用构造用于修改正则表达式以启用 either/or 匹配。
        |    匹配以竖线 (|) 字符分隔的任何一个元素。  th(e|is|at)    "this is the day. " 中的 "the" 和 "this"
        (?( expression )yes | no )    如果正则表达式模式由 expression 匹配指定,则匹配 yes;否则匹配可选的 no 部分。 expression 被解释为零宽度断言。
        (?( name )yes | no )    如果 name 或已命名或已编号的捕获组具有匹配,则匹配 yes;否则匹配可选的 no。
    替换:替换模式中使用的正则表达式
    杂项构造
    Regex类:用于表示一个正则表达式
        匹配了以 'S' 开头的单词:
        MatchCollection mc = Regex.Matches(text, @"\bS\S*");
         foreach (Match m in mc)
         {
            Console.WriteLine(m);
         }
        匹配了以 'm' 开头以 'e' 结尾的单词:@"\bm\S*e\b"
        替换多余的空格:
        string input = "Hello   World   ";
        string pattern = "\\s+";
        string replacement = " ";
        Regex rgx = new Regex(pattern);
        string result = rgx.Replace(input, replacement);
        //输出结果
        Original String: Hello   World   
        Replacement String: Hello World   

29.异常处理
    异常是在程序执行期间出现的问题。C# 中的异常是对程序运行时出现的特殊情况的一种响应,比如尝试除以零。

    异常提供了一种把程序控制权从某个部分转移到另一个部分的方式。C# 异常处理时建立在四个关键词之上的:try、catch、finally 和 throw。

    try:一个 try 块标识了一个将被激活的特定的异常的代码块。后跟一个或多个 catch 块。
    catch:程序通过异常处理程序捕获异常。catch 关键字表示异常的捕获。
    finally:finally 块用于执行给定的语句,不管异常是否被抛出都会执行。例如,如果您打开一个文件,不管是否出现异常文件都要被关闭。
    throw:当问题出现时,程序抛出一个异常。使用 throw 关键字来完成。
    语法:假设一个块将出现异常,一个方法使用 try 和 catch 关键字捕获异常。try/catch 块内的代码为受保护的代码,使用 try/catch 语法如下所示:
    try
    {
    // 引起异常的语句
    }
    catch( ExceptionName e1 )
    {
    // 错误处理代码
    }
    catch( ExceptionName e2 )
    {
    // 错误处理代码
    }
    catch( ExceptionName eN )
    {
    // 错误处理代码
    }
    finally
    {
    // 要执行的语句
    }
    可以列出多个 catch 语句捕获不同类型的异常,以防 try 块在不同的情况下生成多个异常。
    
    C#中的异常类
        C# 异常是使用类来表示的。C# 中的异常类主要是直接或间接地派生于 System.Exception 类。
        System.ApplicationException 和 System.SystemException 类是派生于 System.Exception 类的异常类。
        System.ApplicationException 类支持由应用程序生成的异常。所以程序员定义的异常都应派生自该类。
        System.SystemException 类是所有预定义的系统异常的基类。
        一些派生自 System.SystemException 类的预定义的异常类:
            System.IO.IOException    处理 I/O 错误。
            System.IndexOutOfRangeException    处理当方法指向超出范围的数组索引时生成的错误。
            System.ArrayTypeMismatchException    处理当数组类型不匹配时生成的错误。
            System.NullReferenceException    处理当依从一个空对象时生成的错误。
            System.DivideByZeroException    处理当除以零时生成的错误。
            System.InvalidCastException    处理在类型转换期间生成的错误。
            System.OutOfMemoryException    处理空闲内存不足生成的错误。
            System.StackOverflowException    处理栈溢出生成的错误。
    异常处理:C# 以 try 和 catch 块的形式提供了一种结构化的异常处理方案。使用这些块,把核心程序语句与错误处理语句分离开。
              这些错误处理块是使用 try、catch 和 finally 关键字实现的。        
    自定义异常:派生自 ApplicationException 类
        public class TempIsZeroException: ApplicationException
        {
        public TempIsZeroException(string message): base(message)
            {
            }
        }
    抛出异常:如果异常是直接或间接派生自 System.Exception 类,您可以抛出一个对象。您可以在 catch 块中使用 throw 语句来抛出当前的对象,
        catch(Exception e){throw e;}
30.文件的输入和输出
    一个 文件 是一个存储在磁盘中带有指定名称和目录路径的数据集合。当打开文件进行读写时,它变成一个 流。
    从根本上说,流是通过通信路径传递的字节序列。
    有两个主要的流:输入流 和 输出流。输入流用于从文件读取数据(读操作),输出流用于向文件写入数据(写操作)。
    
    C# I/O
    System.IO 命名空间有各种不同的类,用于执行各种文件操作,如创建和删除文件、读取或写入文件,关闭文件等。
    一些 System.IO 命名空间中常用的非抽象类:
        BinaryReader    从二进制流读取原始数据。
        BinaryWriter    以二进制格式写入原始数据。
        BufferedStream    字节流的临时存储。
        Directory    有助于操作目录结构。
        DirectoryInfo    用于对目录执行操作。
        DriveInfo    提供驱动器的信息。
        File    有助于处理文件。
        FileInfo    用于对文件执行操作。
        FileStream    用于文件中任何位置的读写。
        MemoryStream    用于随机访问存储在内存中的数据流。
        Path    对路径信息执行操作。
        StreamReader    用于从字节流中读取字符。
        StreamWriter    用于向一个流中写入字符。
        StringReader    用于读取字符串缓冲区。
        StringWriter    用于写入字符串缓冲区。
        
    FileStream:有助于文件的读写与关闭。该类派生自抽象类 Stream。使用FileStream可创建或打开文件
        创建语法:FileStream fs = new FileStream(fileName,FileMode fmEnum,FileAccess faEnum,FileShare fsEnum); FileShare可选
        实例:FileStream F = new FileStream("sample.txt", FileMode.Open, FileAccess.Read, FileShare.Read);
        FileMode 枚举定义了各种打开文件的方法。FileMode 枚举的成员有:
            Append:打开一个已有的文件,并将光标放置在文件的末尾。如果文件不存在,则创建文件。
            Create:创建一个新的文件。如果文件已存在,则删除旧文件,然后创建新文件。
            CreateNew:指定操作系统应创建一个新的文件。如果文件已存在,则抛出异常。
            Open:打开一个已有的文件。如果文件不存在,则抛出异常。
            OpenOrCreate:指定操作系统应打开一个已有的文件。如果文件不存在,则用指定的名称创建一个新的文件打开。
            Truncate:打开一个已有的文件,文件一旦打开,就将被截断为零字节大小。然后我们可以向文件写入全新的数据,但是保留文件的初始创建日期。如果文件不存在,则抛出异常。
        FileAccess 枚举的成员有:Read、ReadWrite 和 Write。    
        FileShare 枚举的成员有:
            Inheritable:允许文件句柄可由子进程继承。Win32 不直接支持此功能。
            None:谢绝共享当前文件。文件关闭前,打开该文件的任何请求(由此进程或另一进程发出的请求)都将失败。
            Read:允许随后打开文件读取。如果未指定此标志,则文件关闭前,任何打开该文件以进行读取的请求(由此进程或另一进程发出的请求)都将失败。但是,即使指定了此标志,仍可能需要附加权限才能够访问该文件。
            ReadWrite:允许随后打开文件读取或写入。如果未指定此标志,则文件关闭前,任何打开该文件以进行读取或写入的请求(由此进程或另一进程发出)都将失败。但是,即使指定了此标志,仍可能需要附加权限才能够访问该文件。
            Write:允许随后打开文件写入。如果未指定此标志,则文件关闭前,任何打开该文件以进行写入的请求(由此进程或另一进过程发出的请求)都将失败。但是,即使指定了此标志,仍可能需要附加权限才能够访问该文件。
            Delete:允许随后删除文件。
        使用实例:
            using System;
            using System.IO;
            
            namespace FileIOApplication
            {
                class Program
                {
                    static void Main(string[] args)
                    {
                        FileStream F = new FileStream("test.dat", 
                        FileMode.OpenOrCreate, FileAccess.ReadWrite);
            
                        for (int i = 1; i <= 20; i++)
                        {
                            F.WriteByte((byte)i);
                        }
            
                        F.Position = 0;
            
                        for (int i = 0; i <= 20; i++)
                        {
                            Console.Write(F.ReadByte() + " ");
                        }
                        F.Close();
                        Console.ReadKey();
                        //输出结果:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 -1
                    }
                }
            }
    文本文件的读写:StreamReader 和 StreamWriter 类用于文本文件的数据读写。这些类从抽象基类 Stream 继承,Stream 支持文件流的字节读写。
        StreamReader 类,继承自抽象基类 TextReader,表示阅读器读取一系列字符
            常用方法:
            public override void Close(); 关闭 StreamReader 对象和基础流,并释放任何与读者相关的系统资源。
            public override int Peek();  返回下一个可用的字符,但不使用
            public override int Read(); 从输入流中读取下一个字符,并把字符位置往前移一个字符。
            实例:从某文件中一行一行读取内容并输出
                using System;
                using System.IO;
                
                namespace FileApplication
                {
                    class Program
                    {
                        static void Main(string[] args)
                        {
                            try
                            {
                                // 创建一个 StreamReader 的实例来读取文件 
                                // using 语句也能关闭 StreamReader
                                using (StreamReader sr = new StreamReader("c:/jamaica.txt", Encoding.UTF8))
                                {
                                    string line;
                                
                                    // 从文件读取并显示行,直到文件的末尾 
                                    while ((line = sr.ReadLine()) != null)
                                    {
                                        Console.WriteLine(line);
                                    }
                                }
                            }
                            catch (Exception e)
                            {
                                // 向用户显示出错消息
                                Console.WriteLine("The file could not be read:");
                                Console.WriteLine(e.Message);
                            }
                            Console.ReadKey();
                        }
                    }
                }
        StreamWriter 类继承自抽象类 TextWriter,表示编写器写入一系列字符。
            常用方法:
            public override void Close(); 关闭当前的 StreamWriter 对象和基础流。
            public override void Flush();清理当前编写器的所有缓冲区,使得所有缓冲数据写入基础流。
            public virtual void Write(bool value) 把一个布尔值的文本表示形式写入到文本字符串或流。(继承自 TextWriter。)
            public override void Write( char value ) 把一个字符写入到流。
            public virtual void Write( decimal value ) 把一个十进制值的文本表示形式写入到文本字符串或流。
            public virtual void Write( double value ) 把一个 8 字节浮点值的文本表示形式写入到文本字符串或流。
            public virtual void Write( int value ) 把一个 4 字节有符号整数的文本表示形式写入到文本字符串或流。
            public override void Write( string value ) 把一个字符串写入到流。
            public virtual void WriteLine() 把行结束符写入到文本字符串或流。
            实例:使用 StreamWriter 类向文件写入文本数据
                using System;
                using System.IO;
                
                namespace FileApplication
                {
                    class Program
                    {
                        static void Main(string[] args)
                        {
                
                            string[] names = new string[] {"Zara Ali", "Nuha Ali"};
                            using (StreamWriter sw = new StreamWriter("names.txt"))
                            {
                                foreach (string s in names)
                                {
                                    sw.WriteLine(s);
                
                                }
                            }
                
                            // 从文件中读取并显示每行
                            string line = "";
                            using (StreamReader sr = new StreamReader("names.txt"))
                            {
                                while ((line = sr.ReadLine()) != null)
                                {
                                    Console.WriteLine(line);
                                }
                            }
                            Console.ReadKey();
                            //最终会给names.txt中添加内容
                            //Zara Ali
                            //Nuha Ali
                        }
                    }
                }
    二进制文件的读写:BinaryReader 和 BinaryWriter 类用于二进制文件的读写。
        BinaryReader 类用于从文件读取二进制数据。一个 BinaryReader 对象通过向它的构造函数传递 FileStream 对象而被创建。
            常用方法:
            1    public override void Close()
            关闭 BinaryReader 对象和基础流。
            2    public virtual int Read()
            从基础流中读取字符,并把流的当前位置往前移。
            3    public virtual bool ReadBoolean()
            从当前流中读取一个布尔值,并把流的当前位置往前移一个字节。
            4    public virtual byte ReadByte()
            从当前流中读取下一个字节,并把流的当前位置往前移一个字节。
            5    public virtual byte[] ReadBytes( int count )
            从当前流中读取指定数目的字节到一个字节数组中,并把流的当前位置往前移指定数目的字节。
            6    public virtual char ReadChar()
            从当前流中读取下一个字节,并把流的当前位置按照所使用的编码和从流中读取的指定的字符往前移。
            7    public virtual char[] ReadChars( int count )
            从当前流中读取指定数目的字节,在一个字符数组中返回数组,并把流的当前位置按照所使用的编码和从流中读取的指定的字符往前移。
            8    public virtual double ReadDouble()
            从当前流中读取一个 8 字节浮点值,并把流的当前位置往前移八个字节。
            9    public virtual int ReadInt32()
            从当前流中读取一个 4 字节有符号整数,并把流的当前位置往前移四个字节。
            10    public virtual string ReadString()
            从当前流中读取一个字符串。字符串以长度作为前缀,同时编码为一个七位的整数。
        BinaryWriter 类用于向文件写入二进制数据。一个 BinaryWriter 对象通过向它的构造函数传递 FileStream 对象而被创建。
            常用方法:
            1    public override void Close()
            关闭 BinaryWriter 对象和基础流。
            2    public virtual void Flush()
            清理当前编写器的所有缓冲区,使得所有缓冲数据写入基础设备。
            3    public virtual long Seek( int offset, SeekOrigin origin )
            设置当前流内的位置。
            4    public virtual void Write( bool value )
            把一个单字节的布尔值写入到当前流中,0 表示 false,1 表示 true。
            5    public virtual void Write( byte value )
            把一个无符号字节写入到当前流中,并把流的位置往前移一个字节。
            6    public virtual void Write( byte[] buffer )
            把一个字节数组写入到基础流中。
            7    public virtual void Write( char ch )
            把一个 Unicode 字符写入到当前流中,并把流的当前位置按照所使用的编码和要写入到流中的指定的字符往前移。
            8    public virtual void Write( char[] chars )
            把一个字符数组写入到当前流中,并把流的当前位置按照所使用的编码和要写入到流中的指定的字符往前移。
            9    public virtual void Write( double value )
            把一个 8 字节浮点值写入到当前流中,并把流位置往前移八个字节。
            10    public virtual void Write( int value )
            把一个 4 字节有符号整数写入到当前流中,并把流位置往前移四个字节。
            11    public virtual void Write( string value )
            把一个以长度为前缀的字符串写入到 BinaryWriter 的当前编码的流中,并把流的当前位置按照所使用的编码和要写入到流中的指定的字符往前移。
        实例:
            using System;
            using System.IO;
            
            namespace BinaryFileApplication
            {
                class Program
                {
                    static void Main(string[] args)
                    {
                        BinaryWriter bw;
                        BinaryReader br;
                        int i = 25;
                        double d = 3.14157;
                        bool b = true;
                        string s = "I am happy";
                        // 创建文件
                        try
                        {
                            bw = new BinaryWriter(new FileStream("mydata",
                                            FileMode.Create));
                        }
                        catch (IOException e)
                        {
                            Console.WriteLine(e.Message + "\n Cannot create file.");
                            return;
                        }
                        // 写入文件
                        try
                        {
                            bw.Write(i);
                            bw.Write(d);
                            bw.Write(b);
                            bw.Write(s);
                        }
                        catch (IOException e)
                        {
                            Console.WriteLine(e.Message + "\n Cannot write to file.");
                            return;
                        }
            
                        bw.Close();
                        // 读取文件
                        try
                        {
                            br = new BinaryReader(new FileStream("mydata",
                                            FileMode.Open));
                        }
                        catch (IOException e)
                        {
                            Console.WriteLine(e.Message + "\n Cannot open file.");
                            return;
                        }
                        try
                        {
                            i = br.ReadInt32();
                            Console.WriteLine("Integer data: {0}", i);
                            d = br.ReadDouble();
                            Console.WriteLine("Double data: {0}", d);
                            b = br.ReadBoolean();
                            Console.WriteLine("Boolean data: {0}", b);
                            s = br.ReadString();
                            Console.WriteLine("String data: {0}", s);
                        }
                        catch (IOException e)
                        {
                            Console.WriteLine(e.Message + "\n Cannot read from file.");
                            return;
                        }
                        br.Close();
                        Console.ReadKey();
                    }
                }
            }
    Windows文件系统的操作:使用各种目录和文件相关的类来操作目录和文件,比如 DirectoryInfo 类和 FileInfo 类
        DirectoryInfo 类派生自 FileSystemInfo 类。它提供了各种用于创建、移动、浏览目录和子目录的方法。该类不能被继承。
            常用属性:
                1    Attributes
                获取当前文件或目录的属性。
                2    CreationTime
                获取当前文件或目录的创建时间。
                3    Exists
                获取一个表示目录是否存在的布尔值。
                4    Extension
                获取表示文件存在的字符串。
                5    FullName
                获取目录或文件的完整路径。
                6    LastAccessTime
                获取当前文件或目录最后被访问的时间。
                7    Name
                获取该 DirectoryInfo 实例的名称。
            常用方法:
                1    public void Create()
                创建一个目录。
                2    public DirectoryInfo CreateSubdirectory( string path )
                在指定的路径上创建子目录。指定的路径可以是相对于 DirectoryInfo 类的实例的路径。
                3    public override void Delete()
                如果为空的,则删除该 DirectoryInfo。
                4    public DirectoryInfo[] GetDirectories()
                返回当前目录的子目录。
                5    public FileInfo[] GetFiles()
                从当前目录返回文件列表。
        FileInfo 类派生自 FileSystemInfo 类。它提供了用于创建、复制、删除、移动、打开文件的属性和方法,且有助于 FileStream 对象的创建。该类不能被继承。
            常用属性:
                1    Attributes
                获取当前文件的属性。
                2    CreationTime
                获取当前文件的创建时间。
                3    Directory
                获取文件所属目录的一个实例。
                4    Exists
                获取一个表示文件是否存在的布尔值。
                5    Extension
                获取表示文件存在的字符串。
                6    FullName
                获取文件的完整路径。
                7    LastAccessTime
                获取当前文件最后被访问的时间。
                8    LastWriteTime
                获取文件最后被写入的时间。
                9    Length
                获取当前文件的大小,以字节为单位。
                10    Name
                获取文件的名称。
            常用方法:
                    1    public StreamWriter AppendText()
                    创建一个 StreamWriter,追加文本到由 FileInfo 的实例表示的文件中。
                    2    public FileStream Create()
                    创建一个文件。
                    3    public override void Delete()
                    永久删除一个文件。
                    4    public void MoveTo( string destFileName )
                    移动一个指定的文件到一个新的位置,提供选项来指定新的文件名。
                    5    public FileStream Open( FileMode mode )
                    以指定的模式打开一个文件。
                    6    public FileStream Open( FileMode mode, FileAccess access )
                    以指定的模式,使用 read、write 或 read/write 访问,来打开一个文件。
                    7    public FileStream Open( FileMode mode, FileAccess access, FileShare share )
                    以指定的模式,使用 read、write 或 read/write 访问,以及指定的分享选项,来打开一个文件。
                    8    public FileStream OpenRead()
                    创建一个只读的 FileStream。
                    9    public FileStream OpenWrite()
                    创建一个只写的 FileStream。
        实例-遍历指定目录下所有文件的名称和大小(包含子目录)
            using System;
            using System.IO;
            
            namespace WindowsFileApplication
            {
                class Program
                {
                    public static void SearchFile(string path)
                    {
                        // 创建一个 DirectoryInfo 对象
                        DirectoryInfo mydir = new DirectoryInfo(path); //@"c:\Windows"
                
                        // 获取目录中的文件以及它们的名称和大小
                        FileInfo [] f = mydir.GetFiles();
                        foreach (FileInfo file in f)
                        {
                            Console.WriteLine("File Name: {0} Size: {1}",
                                                file.Name, file.Length);
                        }
                        
                        //遍历目录下的子目录
                        DirectoryInfo[] dList = mydir.GetDirectories();
                        foreach (DirectoryInfo d in dList)
                        {
                            SearchFile(d.FullName);
                        }
                    }
                    static void Main(string[] args)
                    {    
                        Console.WriteLine("请输入路径:");
                        string path = Console.ReadLine();
                        if (!Directory.Exists(path))
                        {
                            Console.WriteLine("路径不存在!");
                            return;
                        }
                        Program.SearchFile(path);
                    }
                }
            }
    
    扩展笔记:
        1.文件和文件夹的路径操作都在Path类中。另外还可以用Environment类,里面包含环境和程序的信息。
        string dirPath = @"D:\TestDir";
        string filePath = @"D:\TestDir\TestFile.txt"; 
        Console.WriteLine("<<<<<<<<<<<{0}>>>>>>>>>>", "文件路径");
        //获得当前路径
        Console.WriteLine(Environment.CurrentDirectory);
        //文件或文件夹所在目录
        Console.WriteLine(Path.GetDirectoryName(filePath));     //D:\TestDir
        Console.WriteLine(Path.GetDirectoryName(dirPath));      //D:\
        //文件扩展名
        Console.WriteLine(Path.GetExtension(filePath));         //.txt
        //文件名
        Console.WriteLine(Path.GetFileName(filePath));          //TestFile.txt
        Console.WriteLine(Path.GetFileName(dirPath));           //TestDir
        Console.WriteLine(Path.GetFileNameWithoutExtension(filePath)); //TestFile
        //绝对路径
        Console.WriteLine(Path.GetFullPath(filePath));          //D:\TestDir\TestFile.txt
        Console.WriteLine(Path.GetFullPath(dirPath));           //D:\TestDir  
        //更改扩展名
        Console.WriteLine(Path.ChangeExtension(filePath, ".jpg"));//D:\TestDir\TestFile.jpg
        //根目录
        Console.WriteLine(Path.GetPathRoot(dirPath));           //D:\      
        //生成路径
        Console.WriteLine(Path.Combine(new string[] { @"D:\", "BaseDir", "SubDir", "TestFile.txt" })); //D:\BaseDir\SubDir\TestFile.txt
        //生成随即文件夹名或文件名
        Console.WriteLine(Path.GetRandomFileName());
        //创建磁盘上唯一命名的零字节的临时文件并返回该文件的完整路径
        Console.WriteLine(Path.GetTempFileName());
        //返回当前系统的临时文件夹的路径
        Console.WriteLine(Path.GetTempPath());
        //文件名中无效字符
        Console.WriteLine(Path.GetInvalidFileNameChars());
        //路径中无效字符
        Console.WriteLine(Path.GetInvalidPathChars()); 

31.特性
    特性(Attribute)是用于在运行时传递程序中各种元素(比如类、方法、结构、枚举、组件等)的行为信息的声明性标签。您可以通过使用特性向程序添加声明性信息。
    一个声明性标签是通过放置在它所应用的元素前面的方括号([ ])来描述的。
    特性(Attribute)用于添加元数据,如编译器指令和注释、描述、方法、类等其他信息。.Net 框架提供了两种类型的特性:预定义特性和自定义特性。
    
    规定特性(Attribute)语法:[attribute(positional_parameters, name_parameter = value, ...)] element
        特性(Attribute)的名称和值是在方括号内规定的,放置在它所应用的元素之前。positional_parameters 规定必需的信息,name_parameter 规定可选的信息。
    预定义特性
        .NET框架提供的三种预定义特性:
        AttributeUsage:描述了如何使用一个自定义特性类。它规定了特性可应用到的项目的类型
            规定语法:[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 时打印调试信息,release 时取消打印。
            这个预定义特性标记了一个条件方法,其执行依赖于指定的预处理标识符。它会引起方法调用的条件编译,取决于指定的值,比如 Debug 或 Trace。例如,当调试代码时显示变量的值。
            规定语法:[Conditional(conditionalSymbol)] 例如:[Conditional("DEBUG")]
            实例:
                #define DEBUG
                using System;
                using System.Diagnostics;
                public class Myclass
                {
                    [Conditional("DEBUG")]
                    public static void Message(string msg)
                    {
                        Console.WriteLine(msg);
                    }
                }
                class Test
                {
                    static void function1()
                    {
                        Myclass.Message("In Function 1.");
                        function2();
                    }
                    static void function2()
                    {
                        Myclass.Message("In Function 2.");
                    }
                    public static void Main()
                    {
                        Myclass.Message("In Main function.");
                        function1();
                        Console.ReadKey();
                        //输出结果
                        In Main function.
                        In Function 1.
                        In Function 2.
                    }
                }

        Obsolete:当程序修改时,某个方法弃用了,使用 Obsolete 做为标识
            这个预定义特性标记了不应被使用的程序实体。它可以让您通知编译器丢弃某个特定的目标元素。
            例如,当一个新方法被用在一个类中,但是您仍然想要保持类中的旧方法,您可以通过显示一个应该使用新方法,而不是旧方法的消息,来把它标记为 obsolete(过时的)。
            规定语法:[Obsolete(message)] [Obsolete(message,iserror)]
                message是字符串,描述项目什么时候过时以及该替代使用什么
                iserror:布尔值,如果为true,编译器把该项目的使用当作一个错误,默认为false(编译器生成一个警告)
            实例:
                using System;
                public class MyClass
                {
                [Obsolete("Don't use OldMethod, use NewMethod instead", true)]
                static void OldMethod()
                { 
                    Console.WriteLine("It is the old method");
                }
                static void NewMethod()
                { 
                    Console.WriteLine("It is the new method"); 
                }
                public static void Main()
                {
                    OldMethod();
                    //输出结果:Don't use OldMethod, use NewMethod instead
                }
                }
        创建自定义特新
            .NET允许创建自定义特性,用于存储声明性的信息,且可在运行时被检索。该信息根据设计标准和应用程序需要,可与任何目标元素相关。
            创建并使用自定义特性包含4步:声明、构建、在目标程序元素上应用、通过反射访问特性
                通过反射访问特性 包含编写一个简单的程序来读取元数据以便查找各种符号。元数据是用于描述其他数据的数据和信息。该程序应使用反射来在运行时访问特性。
            声明自定义特性:派生自 System.Attribute 类。
                实例:
                // 一个自定义特性 BugFix 被赋给类及其成员
                [AttributeUsage(AttributeTargets.Class |
                AttributeTargets.Constructor |
                AttributeTargets.Field |
                AttributeTargets.Method |
                AttributeTargets.Property,
                AllowMultiple = true)]
                
                public class DeBugInfo : System.Attribute

            构建自定义特性:该特性存储调试程序获得的信息,存储以下信息:BUG代码编号、辨认该BUG的开发人员名字、最后一次审查该代码的日期、一个存储开发人员标记的字符串信息
                实例:
                // 一个自定义特性 BugFix 被赋给类及其成员
                [AttributeUsage(AttributeTargets.Class |
                AttributeTargets.Constructor |
                AttributeTargets.Field |
                AttributeTargets.Method |
                AttributeTargets.Property,
                AllowMultiple = true)]
                
                public class DeBugInfo : System.Attribute
                {
                private int bugNo;
                private string developer;
                private string lastReview;
                public string message;
                
                public DeBugInfo(int bg, string dev, string d)
                {
                    this.bugNo = bg;
                    this.developer = dev;
                    this.lastReview = d;
                }
                
                public int BugNo
                {
                    get
                    {
                        return bugNo;
                    }
                }
                public string Developer
                {
                    get
                    {
                        return developer;
                    }
                }
                public string LastReview
                {
                    get
                    {
                        return lastReview;
                    }
                }
                public string Message
                {
                    get
                    {
                        return message;
                    }
                    set
                    {
                        message = value;
                    }
                }
                }
            在目标程序上应用自定义特性:
                [DeBugInfo(45, "Zara Ali", "12/8/2012", Message = "Return type mismatch")]
                [DeBugInfo(49, "Nuha Ali", "10/10/2012", Message = "Unused variable")]
                class Rectangle
                {
                // 成员变量
                protected double length;
                protected double width;
                public Rectangle(double l, double w)
                {
                    length = l;
                    width = w;
                }
                [DeBugInfo(55, "Zara Ali", "19/10/2012",
                Message = "Return type mismatch")]
                public double GetArea()
                {
                    return length * width;
                }
                [DeBugInfo(56, "Zara Ali", "19/10/2012")]
                public void Display()
                {
                    Console.WriteLine("Length: {0}", length);
                    Console.WriteLine("Width: {0}", width);
                    Console.WriteLine("Area: {0}", GetArea());
                }
                }
            通过反射访问特性:将类或方法的标签信息提取出来,在反射章节详细说明

  • 21
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值