C#程序设计

总结:推荐视频:刘铁锰:C#入门:https://www.bilibili.com/video/av7606481/

中国MOOC 搜唐大仕C# (感觉讲的比较浅,可以捡重点快速浏览,重点看7和11章)

微软官方网站:https://docs.microsoft.com/zh-cn/

入门可以看《C#图解教程》,讲的比较全面,过度到《C#高级编程》和《深入理解C#》。

学习C#前提是下载好Visual Studio,配合书上的代码进行动手练习,动手非常重要

学习路线:https://www.cnblogs.com/wangsea/p/9413600.html

唐大仕视频笔记:

第一课

1.用VS设计winform

2.对象三要素

第二课 C#语言基础

 数组是引用类型,数组定义和赋值需分开进行,new一个a,指向一个空间,对该空间赋值

静态初始化:在定义数组的同时为数组元素分配空间并赋值

int[] a={3,9,8}; 

age是变量,ages是数组名

作业练习:

第三课 面向对象的C#语言

1.索引器

属性和索引就是对字段和方法的扩展,在一定意义上,属性是对字段的访问,索引器是对数组的访问,属性可以实现只读或只写而字段不能,属性的set方法可以对用户指定的值,进行有效检查,确保只有正确的状态才会得到设置

2.类的继承

使用冒号,c#采用单继承,子类subclass,父类baseclass

class  Subclass:BaseClass{

...

}

  • 子类自动地从父类继承所有 
  • 除了继承父类成员,子类还可以:添加新成员,隐藏或修改父类的成员

使用base可以调用父类的字段或方法

is 运算符

if(p is Person):判断一个对象是不是某个类(及其子类)的实例

3.修饰符

访问控制符

protected:逻辑角度       internel:物理角度,是否在一个文件

static:static的字段、方法、属性是属于整个类的

  • static方法中,不能访问实例变量,和this相对立
  • 调用static方法时,直接用类名访问
  • static变量可以用来表示“全局变量”

struct是值类型,不能被继承

4.结构

struct是值类型

实例化使,使用new,但与引用型变量的内存是不同的

  • Point p=new Point(100,80);

值类型变量在赋值时,实行的是字段的copy

  1. Point p1,p2;
  2. p1=p2;

第四课 高级特性

首先,委托的关键字是Delegate ,委托是和类同级别的对象,委托应该声明成Public。下面我们先来看下这段代码:

        public delegate int GreetingDelegate(int a ,int b);//定义委托
        static void Main(string[] args)
        {

            Console.WriteLine(pro(3,4,add));

        }
        public static int pro(int x, int y, GreetingDelegate Gd )
        {
            return Gd(x,y);
        }
        public static int add(int x,int y) {
            return x + y;
        }
上面代码首先,声明一个委托变量,然后再把委托变量作为Pro里面参数 最后返回委托的方法

我们可以得出结论 :

1.委托可以把方法当作参数一样传递

2.委托方法的参数定义能够确定方法可以代表的方法种类

委托出了上面的调用方式外还有一种调用方式:

  public delegate int GreetingDelegate(int a ,int b);//定义委托
        static void Main(string[] args)
        {
            GreetingDelegate d1;
            d1 =pro;
            d1 += add;
            Console.WriteLine( d1(3, 4));
        }
        public static int pro(int x, int y)
        {
            return x-y;
        }
        public static int add(int x,int y) {
            return x + y;

        }

这段代码也是先声明一个委托变量 然后把pro方法赋值给d1最后绑定add方法并调用

结论:

1.我们可以把方法赋值给委托变量,委托变量可以绑定方法(第一次d1=pro是赋值,第二次d1+=add才是绑定方法 而我们调用的d1(3,4)就相当于调用的add(3,4),如果第一次就用+=将出现为赋值对象)

2.委托对象+=方法 (绑定方法)

  委托对象-=方法(取消绑定方法)

3.同一委托对象可以绑定多个方法,并可以依次执行所有绑定方法

委托声明在类外面

1.委托是对函数原型的包装

  1. 委托的声明

        public delegate double MyDelegate(double x);

    2.委托的实例化

       MyDelegated d2=new MyDelegate(obj.myMethod);

    3.委托的调用

       委托变量名(参数列表)

       d2(8.9);

2.委托的合并

多播委托是指在一个委托中注册多个方法

一个委托实例可以“包含”多个函数

用运算符+-   +=   -=动态地增减其中的函数,

3.事件

例子:(没明白)

public delegate void DownloadStartHandler(object sender, DownloadStartEventArgs e);  //声明委托

public delegate void DownloadStartHandler(object sender, DownloadStartEventArgs e);  //声明委托
public class DownloadStartEventArgs

{

    public string Url{ get{ return _url;} set{ _url=value;} }

    private string _url;

 

    public DownloadStartEventArgs( string url ){ this._url = url; }

}
public class Crawler

{

 

    public event DownloadStartHandler DownloadStart;  // 声明事件

    public void Craw()

    {   

        while( true )

        {

            string url = GetNextUrl();

            if( url == null ) break;

            long size = GetSizeOfUrl( url );

 

            if( DownloadStart != null ) //下载开始的事件发生

            {

                DownloadStart( this, new DownloadStartEventArgs(url));

            }
        }
    
class Test

{

    static void Main()

    {

        Crawler crawler = new Crawler("Crawer101", "https://www.pku.edu.cn");
        crawler.DownloadStart += new DownloadStartHandler( ShowStart ); //注册事件        
        crawler.Craw();

    }
}
  static void ShowStart(object sender, DownloadStartEventArgs e){

        Console.WriteLine( (sender as Crawler).Name + "开始下载" + e.Url );

    }

4.Lambda表达式

泛型List——避免强制转换

Lamda表达式:直接用(参数)=> {语句或表达式}

例:new Thread(()=>{ ... }).Start();

5.异常处理

  1. 捕获异常

        try{}

        catch{Exception e}

        finally{}

     2.抛出异常

     if(  xxx)  throw  new someException(信息)

第五章  基础类及常用算法

String 内容不可变,StringBuilder内容可变

StringBuilder类比string类在循环中执行更快

集合类

  • 数组列表ArrayList  ,相当于动态数组
  • 哈希表 Hashtable,用[ ]进行访问,表示获取,增加,删除,修改,提示:用于查询时,比线性搜索的效率要高,可用于程序优化
  • 使用foreach访问数组及集合

第6章 流、文件

  • 文本文件的操作:建立StreamReader,StreamWriter对象
  • 二进制文件操作:FileStream

程序调试的基本手段:

  • 断点:左边单机
  • 跟踪:看程序流程 F10或F11
  • 监视:查看变量,鼠标指向它,或点右键,添加监视

先打断点,鼠标停到变量会显示变量值,点F10或F11跟踪流程

第7章 Windows窗体

布局与事件

窗体布局实例参考My_Explorer_src

控件

掩码文本框:显示需要一定条件的文本框

 FlowLayoutPanel:流式布局控件,添加到它上面的控件会按设定顺序依次排列,并且不支持拖拽到特定位置

Panel:panel为普通容器,没有布局功能,可以拖控件到任意位置

SplitContainer:使用 SplitContainer 控件,可以创建复合的用户界面(通常,在一个面板中的选择决定了在另一个面板中显示哪些对象)。这种排列对于显示和浏览信息非常有用。拥有两个面板使您可以聚合不同区域中的信息,并且用户可以轻松地使用拆分条(也称为“拆分器”)调整面板的大小。

项目右键添加用户控件窗体,处理Paint事件

第8章 绘图及图像

1.绘图基础GDI+

2.绘图对象及绘图方法

pen:画笔

brush:画刷

3.绘件的重绘和双缓冲

framework3以上版本有doublebuffer双缓冲,减少闪烁

第9章 文本处理及正则表达式

第10章 网络信息获取及xml处理

1.网络信息获取的基本方法

查看服务端和浏览器通讯信息:http://www.fidder2.com/          Chrome/FireFox等浏览器按F12,network中查看

使用System.Web提供支持浏览器/服务器通讯的类和接口

WebClient类

2.XML基本操作

Xpath是对xml进行查询的表达式

第11章 多线程与异步编程

1.线程及其控制

线程的同步:

使用join方法:将单独的执行线程合并成一个线程

Thread.Join() 在MSDN中的解释:Blocks the calling thread until the thread represented by this instance terminates.(在此实例表示的线程终止前,阻止调用线程。)

static void Main(string[] args)
{
    Thread thread1 = new Thread(new ThreadStart(Test1));
    thread1.Start();
    thread1.Join();
 
    Thread thread2 = new Thread(new ThreadStart(Test2));
    thread2.Start();
    thread2.Join();
 
    Console.WriteLine("finished.");
    Console.Read();
}
 
static void Test1()
{
    Console.WriteLine("t1 " + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.fff"));
    Thread.Sleep(500);
    Console.WriteLine("t1 " + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.fff"));
    Thread.Sleep(500);
    Console.WriteLine("t1 " + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.fff"));
    Thread.Sleep(500);
    Console.WriteLine("t1 " + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.fff"));
    Thread.Sleep(500);
    Console.WriteLine("t1 " + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.fff"));
    Thread.Sleep(500);
    Console.WriteLine("t1 " + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.fff"));
    Thread.Sleep(500);
    Console.WriteLine("t1 " + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.fff"));
    Thread.Sleep(500);
    Console.WriteLine("t1 " + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.fff"));
    Thread.Sleep(500);
    Console.WriteLine("t1 " + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.fff"));
    Thread.Sleep(500);
    Console.WriteLine("t1 " + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.fff"));
    Thread.Sleep(500);
}
 
static void Test2()
{
    Console.WriteLine("t2 " + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.fff"));
    Thread.Sleep(500);
    Console.WriteLine("t2 " + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.fff"));
    Thread.Sleep(500);
    Console.WriteLine("t2 " + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.fff"));
    Thread.Sleep(500);
    Console.WriteLine("t2 " + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.fff"));
    Thread.Sleep(500);
    Console.WriteLine("t2 " + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.fff"));
    Thread.Sleep(500);
    Console.WriteLine("t2 " + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.fff"));
    Thread.Sleep(500);
    Console.WriteLine("t2 " + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.fff"));
    Thread.Sleep(500);
    Console.WriteLine("t2 " + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.fff"));
    Thread.Sleep(500);
    Console.WriteLine("t2 " + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.fff"));
    Thread.Sleep(500);
    Console.WriteLine("t2 " + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.fff"));
    Thread.Sleep(500);
}
thread1 启动后,调用 Join() 方法,直到 thread1 的任务结束,才轮到 thread2 启动,然后 thread2 也开始任务。实例中,两个线程就按着严格的顺序来执行了。如果 thread2 的执行需要依赖于 thread1 中的完整数据的时候,这种方法就可以很好的确保两个线程的同步性。

lock语句使同一时间只有一个线程可以执行对象或表达式

2.并行编程(多个CPU同时执行任务)

3.异步编程 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading;

 

/// <summary>

/// 异步调用方法总结:

/// 1.BeginEnvoke EndEnvoke

/// 当使用BeginInvoke异步调用方法时,如果方法未执行完,EndInvoke方法就会一直阻塞,直到被调用的方法执行完毕

/// </summary>

class Async1

{

    public delegate int FooDelegate(string s);

    static void Main(string[] args)

    {

        Console.WriteLine("主线程"+Thread.CurrentThread.ManagedThreadId);

 

        FooDelegate fooDelegate = Foo;

        IAsyncResult result= fooDelegate.BeginInvoke("Hello World.", null, null);

        Console.WriteLine("主线程继续执行...");

        //当使用BeginInvoke异步调用方法时,如果方法未执行完,EndInvoke方法就会一直阻塞,直到被调用的方法执行完毕

        int n = fooDelegate.EndInvoke(result);

        Console.WriteLine("回到主线程"+Thread.CurrentThread.ManagedThreadId);

        Console.WriteLine("结果是"+n);

        Console.ReadKey(true);

    }

 

    public static int Foo(string s)

    {

        Console.WriteLine("函数所在线程"+Thread.CurrentThread.ManagedThreadId);

        Console.WriteLine("异步线程开始执行:"+s);

        Thread.Sleep(1000);

        return s.Length;

    }

}

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading;

 

/// <summary>

/// 异步调用方法总结:

/// 回调

/// 异步线程在工作结束后会主动调用我们提供的回调方法,并在回调方法中做相应的处理,例如显示异步调用的结果。

/// </summary>

class Program

{

    public delegate void FooDelegate(string s);

    static void Main(string[] args)

    {

        Console.WriteLine("主线程."+Thread.CurrentThread.ManagedThreadId);

        FooDelegate fooDelegate = Foo;

        fooDelegate.BeginInvoke("Hello world.", 

            FooComepleteCallback, fooDelegate);

        Console.WriteLine("主线程继续执行..."+Thread.CurrentThread.ManagedThreadId);

 

        Console.WriteLine("Press any key to continue...");

        Console.ReadKey(true);

    }

    public static void Foo(string s)

    { 

        Console.WriteLine("函数当前线程:"+Thread.CurrentThread.ManagedThreadId);

        Console.WriteLine(s);

        Thread.Sleep(1000);

    }

    //回调方法要求

    //1.返回类型为void

    //2.只有一个参数IAsyncResult

    public static void FooComepleteCallback(IAsyncResult result)

    {

        Console.WriteLine("回调函数所在线程:"+Thread.CurrentThread.ManagedThreadId);

        (result.AsyncState as FooDelegate).EndInvoke(result);

        Console.WriteLine("回调函数线程结束." + result.AsyncState.ToString());

    }

}

讲await和async:https://www/cnblogs.com/landeanfen/p/4734252.html

1.凡是使用await关键字的方法,都必须打上async标记。

2.async表示方法内有异步方法,调用async方法,会立刻另起线程执行。

3.await只是显示等待线程结束。await表示等待异步方法执行完,并取返回值。

4.所有的async方法返回类型必然是Task或Task<T>,这是异步处理的基础

5.在async方法中遇到await关键字后,当前线程立即返回(到调用方),继续之前的处理逻辑,await关键字之后的代码逻辑,交由新线程处理,当新线程处理完成,可以从新线程返回处理结果到调用线程当中,结束等待

 

using System;

using System.Threading;

using System.Threading.Tasks;

class AsyncSimple1

{

    Task<double> FacAsync(int n)

    {

        return Task<double>.Run( ()=>{

            double s = 1;

            for(int i=1; i<n; i++) s = s*i;

            return s;

        });

    }

    async void Test()

    {

        // 调用异步方法

        double result = await FacAsync(10);

        Console.WriteLine( result); //想想这句在哪个线程

    }

 

    static void Main()

    {

        new AsyncSimple1().Test();

        Console.ReadKey();

    }

}

 第12章 访问数据库

由于Access数据库用得较少,现在用SQLite数据库的人越来越多。SQLite是一个轻量级的桌面数据库,用一个文件来存储所有的表,使用起来十分方便。

https://sqlite.org/ 是其官网,可以下载Sqlite。还可以下载一些图形化的客户端,如https://sqliteexpert.com/v4/SQLiteExpertPersSetup64.exe 还有Navicat等。

如果用Visual Studio,为了访问SQLite,需要下载System.Data.SQLite, 见https://system.data.sqlite.org/index.html/doc/trunk/www/downloads.wiki ,

不过,可以直接从VisualStudio中使用 工具--NuGet包管理--项目的NuGet包管理工具,从搜索中搜索 SQLite,然后点下载安装。

安装后, using System.Data.SQLite 就可以

using System.Data.SQLite; 

   public void Demo()
        {
            //如果不存在,则创建一个空的数据库,
            if(!System.IO.File.Exists("MyDatabase.sqlite"))
                SQLiteConnection.CreateFile("MyDatabase.sqlite");

            //创建一个连接
            SQLiteConnection m_dbConnection = new SQLiteConnection("Data Source=MyDatabase.sqlite;Version=3;");
            m_dbConnection.Open();

            //创建一个数据表
            string sql = "create table book (title varchar(20), author varchar(10), pages int)";
            SQLiteCommand command = new SQLiteCommand(sql, m_dbConnection);
            try
            {
                command.ExecuteNonQuery();
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex);
            }

            //插入一些记录
            sql = "insert into book (title, author, pages) values ('C#程序设计教程', '唐大仕', 570)";
            command = new SQLiteCommand(sql, m_dbConnection);
            command.ExecuteNonQuery();

            sql = "insert into book (title, author, pages) values ('Java程序设计', '唐大仕', 390)";
            command = new SQLiteCommand(sql, m_dbConnection);
            command.ExecuteNonQuery();

            sql = "insert into book (title, author, pages) values ('Visual C++.NET程序设计', '唐大仕,刘光', 410)";
            command = new SQLiteCommand(sql, m_dbConnection);
            command.ExecuteNonQuery();

            //使用sql查询语句,并显示结果
            sql = "select * from book order by pages desc";
            command = new SQLiteCommand(sql, m_dbConnection);
            SQLiteDataReader reader = command.ExecuteReader();
            while (reader.Read())
                Console.WriteLine("书名: " + reader["title"] + "\t页数: " + reader["pages"]);
            
            //关闭连接
            m_dbConnection.Close();

            Console.ReadLine();


        }

Mysql:开源   Oracle:大中型企业在用

2.数据库的访问方式:ADO.NET

3.访问数据库的方法

第13章 深入理解C#语言

1.类型与转换

2.变量及其传递

3.动态类型确定

4.C# 语言新特性

Hello World -- 您的第一个程序 6 C# 程序的一般结构 8 Main() 和命令行自变量 9 命令行自变量 10 显示命令行自变量 12 使用 foreach 存取命令行自变量 13 Main() 传回值 14 数据型别 15 在变量宣告中指定型别 16 转型和型别转换 21 Boxing 和 Unboxing 24 使用 as 和 is 运算符进行安全转型 27 将字节数组转换为 int 29 将 string 转换为 int 30 在十六进制字符串和数字型别间转换 32 数组 34 将数组当做对象 35 一维数组 36 多维数组 36 不规则数组 37 在数组上使用 foreach 39 传递数组当做参数 40 使用 ref 和 out 传递数组 42 隐含型别数组 44 字符串 45 字符串基本概念 46 串连多个字符串 53 修改字符串内容 56 比较字符串 60 分割字符串 65 使用字符串方法搜寻字符串 66 使用正则表达式搜寻字符串 67 判断字符串是否表示数值 70 将 String 转换为 DateTime 71 在旧版编码方式和 Unicode 间转换 72 转换 RTF 为纯文本 74 语句、表达式和运算符 75 语句 76 表达式 81 运算符 83 匿名函式 86 Lambda 表达式 88 在查询中使用 Lambda 表达式 92 在 LINQ 之外使用 Lambda 表达式 94 匿名方法 94 可多载的运算符 97 转换运算符 98 使用转换运算符 99 在结构之间实作用户定义的转换 101 使用运算符多载建立复数类别 103 覆写 Equals() 和运算符 == 的方针 105 类别和结构 108 类别 112 对象 115 结构 118 使用结构 119 继承 122 多型 126 使用 Override 和 New 关键词进行版本控制 132 了解使用 Override 和 New 关键词的时机 135 覆写 ToString 方法 137 抽象和密封类别以及类别成员 138 定义抽象属性 140 静态类别和静态类别成员 144 成员 148 存取修饰词 149 字段 151 常数 153 在 C# 中定义常数 155 属性 156 使用属性 157 接口属性 165 非对称存取子的存取范围 168 宣告和使用读取/写入属性 173 自动实作的属性 176 使用自动实作的属性来实作轻量型类别 176 方法 177 传递参数 181 传递实值型别的参数 181 传递参考型别的参数 184 了解传递结构和传递类别参考给方法之间的差异 187 隐含型别局部变量 188 在查询表达式中使用隐含型别局部变量和数组 191 扩充方法 192 实作和呼叫自定义扩充方法 197 建立列举型别的新方法 199 建构函式 200 使用建构函式 201 实例建构函式 204 私用建构函式 209 静态建构函式 211 撰写复制建构函式 213 对象和集合初始化表达式 217 初始化对象但不呼叫建构函式 219 使用集合初始化表达式来初始化字典 220 嵌套类型 221 部分类别和方法 222 限制 224 匿名型别 227 在查询中传回项目属性的子集 229 界面 230 明确界面实作 232 明确实作接口成员 234 使用继承明确实作接口成员 236 索引器 239 使用索引器 240 界面中的索引器 244 属性与索引器之间的比较 246 使用委派 250 使用具名和匿名方法委派的比较 253 使用委派取代接口的时机 255 委派中的 Covariance 和 Contravariance 256 组合委派 (多播委派) 258 宣告、产生和使用委派 259 事件 264 订阅及取消订阅事件 265 发行符合 .NET Framework 方针的事件 267 在衍生类别中引发基类事件 271 实作界面事件 276 使用字典储存事件实例 280 实作自定义事件存取子 283 泛型 284 泛型简介 285 泛型的优点 287 泛型型别参数 289 泛型类别 295 泛型界面 298 泛型方法 304 泛型和数组 306 泛型委派 307 泛型程序代码中的默认关键词 308 C++ 样板和 C# 泛型之间的差异 309 运行时间中的泛型 310 .NET Framework 类别库中的泛型 311 泛型和反映 312 泛型和属性 313 泛型型别中的变异数 314 LINQ 查询表达式 325 查询表达式基本概念 328 在 C# 中撰写 LINQ 查询 336 查询对象集合 339 从方法传回查询 341 将查询的结果储存在内存中 343 使用各种不同方式分组结果 344 将群组包含在群组中 352 针对分组作业执行子查询 353 在运行时间动态指定述词筛选条件 362 执行内部联结 364 执行群组联结 372 执行左外部联接 376 排序 Join 子句的结果 378 使用复合索引键执行联结 381 执行自定义联结作业 382 处理查询表达式中的 Null 值 387 处理查询表达式中的例外状况 388 Iterator 390 使用 Iterator 392 建立整数清单的 Iterator 区块 394 建立泛型清单的 Iterator 区块 395 命名空间 398 使用命名空间 399 使用命名空间别名限定符 403 使用 My 命名空间 405 可为 Null 的型别 407 使用可为 Null 的型别 409 Box 处理可为 Null 的型别 413 识别可为 Null 的型别 414 从 bool? 安全转型至 bool 415 Unsafe 程序代码和指标 415 固定大小缓冲区 416 使用 Windows ReadFile 函式 417 指标型别 421 指标转换 422 指标表达式 424 取得指针变量值 424 取得变量地址 425 使用指标存取成员 426 使用指针存取数组元素 428 管理指标 429 递增和递减指标 429 指标的算术运算 430 指标比较 431 使用指针复制字节数组 432 XML 文件批注 434 建议使用的文件批注标签 435 处理 XML 档案 448 文件标签的分隔符 453 使用 XML 文件功能 454 应用程序域 458 在其他应用程序域中执行程序代码 459 建立和使用应用程序域 461 组件和全局程序集缓存 461 Friend 组件 462 判断档案是否为组件 465 加载和卸除组件 466 与其他应用程序共享程序集 466 使用属性 468 明示属性目标 470 使用反映存取属性 472 使用属性建立 C/C++ 等位 475 常见属性 476 全局属性 479 集合类别 483 使用 foreach 存取集合类别 484 使用例外状况 489 例外处理 492 建立和掷回例外状况 495 编译程序所产生的例外状况 498 使用 try/catch 处理例外状况 498 使用 finally 执行清除程序代码 499 拦截非 CLS 例外状况 501 文件系统和登录 502 逐一查看目录树状结构 502 取得档案、文件夹和磁盘驱动器的信息 509 建立档案或文件夹 509 写入文本文件 515 从文本文件读取 516 一次一行读取文本文件 (Visual C#) 516 在登录中建立机码 (Visual C#) 517 写入应用程序事件记录文件 (Visual C#) 518 互操作性 518 使用平台调用播放 WAV 檔 520 范例 COM 类别 523 线程 524 使用线程 525 线程同步处理 526 建立和结束线程 530 同步处理产生者和消费者线程 534 使用线程集区 542 反映 545 C# DLL 547 建立和使用 C# DLL 547 安全性 550
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值