C#高级
根据个人所学以及相关网络查询 ,总结得出C# 高级共分为一下几个章节(待补充)
正则表达式 、泛型 ,集合,委托 ,反射, 特性,匿名方法(lambda 表达表达式),多线程,文件操作 ,异常 等
正则表达式
概念 : 是一种匹配输入文本的模式 .net框架提供了这种匹配模式的正则表达式引擎
小提示 :在项目开发中使用的正则表达式不多,对此不是特别了解
集合
集合:是将一堆数据类型相同的数据放入到一个容器内,该容器就是数组,内存中开辟的一连串的空间 ,集合与数组不相同的是集合提供了特定的方法,能够直接操作其中的数据。
集合分为泛型集合和非泛型集合;
非泛型集合 | 泛型集合 |
---|---|
ArrayList | List |
HashTable | Dictionary |
Queue | Queue |
Stack | Stack |
SortedList | SortedList |
常用的集合:非泛型集合ArrayLIst ,HashTable ;泛型集合 List ,Dictionary ,
仅对常用集合进行讲解
ArrayList :
ArrayList是数组的升级版本。Arraylist提供了多数zaiCollection提供但是不在Array数组中的部分功能 ;ArrayList基于数组实现,是个容量能够自动增长的动态数组。 所以 ArrayList 与数组的操作方式基本类似。
ArrayList 使用示例
//初始化 共有三种初始化方式
//ArrayList listl=new ArrayList();
//ArrayList list2=new ArrayList(listl);
//ArrayList list3=new ArrayList(20);
ArrayList list4 = new ArrayList(){l,2,3,4};
list4.add(5);
String abc="";
for (int i = 0; i < list4 .Count; i++) {
abc += "," + List[i].ToString();
}
console.writeline(abc);
从上面示例代码可得知,ArrayList拥用四种 初始化方法
构造方法 | 作用 |
---|---|
ArrayList() | 创建 ArrayList 的实例,集合的容量是默认初始容量 |
ArrayList(){} | 创建 ArrayList 的实例,直接将数据列表赋给ArrayList |
ArrayList(ICollection c) | 创建 ArrayList 的实例,该实例包含从指定实例中复制的元素,并且初始容量与复制的元素个数相同 |
ArrayList(int capacity) | 创建 ArrayList 的实例,并设置其初始容量 |
操作ArrayList 常用方法 :
总结:
ArrayList能够自动会改变大小,操作元素较为灵活,但是相对于数组来说,效率较低
HashTable
概念 :HashTable (散列表) 实现IDictonary接口,集合中的数据都是以键值对的形式存取,是一种用于处理类似Key,Value 键值对的一种容器。通常通过使用Key用于快速查找元素。HashTable中的键值对都是Object 类型,所以HashTable支持任何类型的键值对。
使用场景:
数据被频率查询;
数据量较大时;
查询字段包含数据类型;
数据类型不唯一;
常用属性及方法
属性/方法 | 用途/功能 |
---|---|
Count | 集合中数据的数量 |
Add() | 集合中添加键值对 |
Remove | 删除指定键 |
Clear | 清空集合 |
ContainKey/Value | 判定集合是否包含指定键/‘值 |
补充 :HashTable 还可通过 【Key】 的形式添加新的键值对;
同时Hash Table在数值进行强制转化类型 类型不符合 会出异常 应当使用 使用as-statements 进行类型转化
StreamReader reader = hashtable[100] as StreamReader;
if (reader == null)
{
Console.WriteLine("西安不是StreamReader型");
}
当我们需要遍历HashTable 需要使用 DictionaryEntry/Var 承接键值对对象
for(DictionaryEntry de in ht) fileht为一个Hashtable实例
{
Console.WriteLine(de.Key);de.Key对应于keyvalue键值对key
Console.WriteLine(de.Value);de.Key对应于keyvalue键值对value
}
注意 注意 注意 新框架中出现 HashMap 类似于 HashTable
HashMap 是.net新框架的用于替换HashTable的类, .net新框架推荐开发人员使用HashMap
HashTable HashMap的区别 :
HashTable 的方法是同步的,HashMap是未经同步的,所以多线程中要手动同步HashMap ;
代码示例:
Map Collections.synchronizedMap(Map m)
HashTable是Dictionary的子类,HashMap是Map接口的一个实现类 ;
HashMap 中null可以作为主键,这样的键只有一个,可以一个键或多个键对应的值为Null .
因此 在HashMap中无法使用 get()方法判断Key是否存在。需要使用 ContainsKey() 进行验证Key是否存在 。
Queue 队列集合
Queue类实在System.collections命名空间下;表示对象的先进先出的集合 。存储在队列中的对象在一端插入(入列),在另一端移除(出列).
属性: Count 获取Queue中包含的元素个数;
常用方法:
方法名 | 描述 |
---|---|
public virtual void Clear(); | 从Queue中移除所有的元素。 |
public virtual bool Contains( object obj ); | 判断某个元素是否在Queue中。 |
public virtual object Dequeue(); | 移除并返回在Queue的开头的对象。 |
public virtual void Enqueue( object obj ); | 向Queue的末尾添加一个对象。 |
public virtual object[] ToArray(); | 复制Queue到一个新的数组中。 |
public virtual void TrimToSize(); | 设置容量为Queue中元素的实际个数。 |
Stack
代表了一个后进先出的对象集合,当您需要对各项进行后进先出的访问时,则需要使用堆栈。像列表中添加一项称为推入元素,从列表中移除元素称为弹出元素.
常用属性
Count : 获取stack中的元素的个数
常用方法
public virtual void Clear();
从 Stack 中移除所有的元素。
2 public virtual bool Contains( object obj );
判断某个元素是否在 Stack 中。
3 public virtual object Peek();
返回在 Stack 的顶部的对象,但不移除它。
4 public virtual object Pop();
移除并返回在 Stack 的顶部的对象。
5 public virtual void Push( object obj );
向 Stack 的顶部添加一个对象。
6 public virtual object[] ToArray();
复制 Stack 到一个新的数组中。
补充 :在C#中堆栈Stack 有两种实现方式:基于数组的顺序堆栈实现,类似列表的链式堆栈实现. 其方式与数据结构中的顺序存储和链式存储类似 在这里不在进行过多阐述
C#Stack链式存储和顺序存储
SortedList
概述:SortedList代表一系列按照键来排序的键值对,可以通过键/索引来访问其中的值。
SortedList 是数组和哈希表的组合,它可以包含一个可使用键/索引 访问各项的列表,使用
索引访问他就是一个动态数组,使用key访问 它就是一个HashTable.
常用的属性:
属性 | 描述 |
---|---|
Capacity | 获取或设置 SortedList 的容量。 |
Count | 获取 SortedList 中的元素个数。 |
IsFixedSize | 获取一个值,表示 SortedList 是否具有固定大小。 |
IsReadOnly | 获取一个值,表示 SortedList 是否只读。 |
Item | 获取或设置与 SortedList 中指定的键相关的值。 |
Keys | 获取 SortedList 中的键。 |
Values | 获取 SortedList 中的值。 |
常用方法:
Sorted常用方法
泛型集合:
在这里仅介绍 List 和dictionary;
List
概述 :List 提供了用于对列表进行搜索,排序和操作的方法。List是 ArrayList 的泛型等效类;
常用属性
名称 | 作用 |
---|---|
Count | 获取列表内包含的元素个数 |
Capactiy | 获取或设置内部数据结构在不调整大小的情况下能够保存到元素个数 |
Item | 获取或设置指定索引处的元素 |
常用方法:
名称 | 作用 |
---|---|
Item( ) | 通过指定索引获取或设置元素。对于List类来说,它是一个索引器。 |
Add( ) | 在List中添加一个对象的公有方法 |
AddRange( ) | 公有方法,在List尾部添加实现了ICollection接口的多个元素 |
BinarySearch( ) | 重载的公有方法,用于在排序的List内使用二分查找来定位指定元素. |
Clear( ) | 在List内移除所有元素 |
Contains( ) | 测试一个元素是否在List内 |
CopyTo( ) | 重载的公有方法,把一个List拷贝到一维数组内 |
Exists( ) | 测试一个元素是否在List内 |
Find( ) | 查找并返回List内的出现的第一个匹配元素 |
FindAll( ) | 查找并返回List内的所有匹配元素 |
GetEnumerator( ) | 重载的公有方法,返回一个用于迭代List的枚举器 |
Getrange( ) | 拷贝指定范围的元素到新的List内 |
IndexOf( ) | 重载的公有方法,查找并返回每一个匹配元素的索引 |
Insert( ) | 在List内插入一个元素 |
InsertRange( ) | 在List内插入一组元素 |
LastIndexOf( ) | 重载的公有方法,查找并返回最后一个匹配元素的索引 |
Remove( ) | 移除与指定元素匹配的第一个元素 |
RemoveAt( ) | 移除指定索引的元素 |
RemoveRange( ) | 移除指定范围的元素 |
Reverse( ) | 反转List内元素的顺序 |
Sort( ) | 对List内的元素进行排序 |
ToArray( ) | 把List内的元素拷贝到一个新的数组内 |
trimToSize( ) | 将容量设置为List中元素的实际数目 |
Dictionary
概念:Dictionary表示键和值的集合。
Dictionary<string, string>是一个泛型
他本身有集合的功能有时候可以把它看成数组
他的结构是这样的:Dictionary<[key], [value]>
他的特点是存入对象是需要与[key]值一一对应的存入该泛型
通过某一个一定的[key]去找到对应的值;
HashTable和Dictionary的区别:
(1).HashTable不支持泛型,而Dictionary支持泛型。
(2). Hashtable 的元素属于 Object 类型,所以在存储或检索值类型时通常发生装箱和拆箱的操作,所以你可能需要进行一些类型转换的操作,而且对于int,float这些值类型还需要进行装箱等操作,非常耗时。
(3).单线程程序中推荐使用 Dictionary, 有泛型优势, 且读取速度较快, 容量利用更充分。多线程程序中推荐使用 Hashtable, 默认的 Hashtable 允许单线程写入, 多线程读取, 对 Hashtable 进一步调用 Synchronized() 方法可以获得完全线程安全的类型. 而 Dictionary 非线程安全, 必须人为使用 lock 语句进行保护, 效率大减。
(4)在通过代码测试的时候发现key是整数型Dictionary的效率比Hashtable快,如果key是字符串型,Dictionary的效率没有Hashtable快。
泛型
概念: 泛型是程序设计语言的一种特性;允许程序员在进行强类型程序设计是通过参数类型化,让其同一个程序代码可以处理不同的数据类型。提高代码的复用率。其程序的参数类型必须在使用前做出类型类型说明;可以简单的理解为程序员在设计程序时并不知道将来程序会会处理什么类型数据,因而将其数据类型作为可变类型 ‘T,只要其他人员在使用时对T进行声明即可;
泛型类使用引用类型;更准确的来说是一种类型母版;主要将其引入参数类型化理念;
特性:
- 提高代码的复用率,保护类型安全以及提高性能
- 创建泛型集合类,.NET 框架类库在 System.Collections.Generic 命名空间中包含了一些新的泛型集合类。您可以使用这些泛型集合类来替代 System.Collections 中的集合类。
- 开发人员根据需要创建自己的泛型方法,泛型类,泛型接口,泛型时间,泛型委托;
- 可以对泛型类进行约束以访问特定数据类型的方法。
- 泛型数据类型中使用的类型的信息可在运行时通过使用反射获取;
反射
概念: 反射是C#中的一种重要的机制,是指程序可以通过访问,检测,和修改它本身的状态和行为的一种能力。程序集包含模块,而模块包含类型,类型又包含成员,反射则封装程序集模块何类型的对象,通过反射机制可以动态获得每个类的类型信息,并创建出动态的实例;
用途:
使用反射可以在运行时查看特性信息;
允许审查集合中的各种类型,以及实例化这些类型;
允许延迟绑定的方法和属性;
允许运行时创建新类型,并使用新类型实例去执行一些任务;
优缺点:
优点
反射提高了程序的灵活性和扩展性;
反射降低耦合度提高程序的自适应力;
允许程序在创建和控制任何类的对象,无需要提前硬编码目标类 ;
缺点:
性能问题,用反射基本上是一种解释操作,用于字段和方法接入时要远慢于直接代码。因此反射机制主要应用在对灵活性和拓展性要求很高的系统框架上,普通程序不建议使用;
使用反射会模糊程序代码的逻辑,降低代码的可读性;
使用反射会根据程序的规模生成相应的meta文件,让程序集文件体积变大;
不安全;如果泛型方法的类型没有进行约束,程序的数据类型需要引用类型,传入的却是值类型,则有可能造成系统直接崩溃;
反射如何使用:
反射的使用是要是几个常用类的使用分别是
System.Reflection.Assembly //加载程序集
System.Reflection.MemberInfo //获取成员集合
System.Reflection.EventInfo //获取事件
System.Reflection.MethodInfo //获取成员方法
System.Reflection.PropertyInfo //获取成员属性
System.Type //获取类型
利用反射动态加载程序集文件
//Assembly assembly = Assembly.Load("KangHui.Common");
***利用反射获取类型
//Type type = typeof(int);
ConvertHelper
***利用反射创建一个对象
//object obj = assembly.CreateInstance("KangHui.Common.ConvertHelper");
//Console.WriteLine(type.ToString());
// Console.WriteLine(typeof(KangHui.Common.ConvertHelper));//KangHui.Common.ConvertHelper
//PropertyInfo[] plist = type.GetProperties();
//5通过类型获取方法的集合
//MethodInfo[] methods = type.GetMethods();
委托
概念: 是可以将方法当作参数传入到另一个方法中;
语法:修饰符 delegate 返回值 名称(参数…)
委托类型:
public delegate void NoReturnNoParams();
public delegate string HasReturnNoParams();
public delegate void NoReturnHasParams(string name);
public delegate string HasReturnHasParams(string name);
.Net内置的两种泛型委托
//Action<>
//Func<>有返回值的委托 注意:该泛型委托最多可以传递16个参数 最后一个是返回值类型
委托的作用:
委托中放入方法,使用委托进行调用;
可以实现程序的解耦性,
C#委托是异步的基础;
使用委托 将方法当参数,可以避免大量的if 语句,同时让程序具有更好的可扩展性;
多播委托:
多播委托:将多个相同类型的方法赋给同一个委托,或者说是将多个方法绑定到同一个委托上;
注意 :如果委托中的方法有返回值,那么我们只能拿到最后的一个返回值;
事件
事件是委托的一个实例,主要是为了保证委托的安全。也可以说事件是一种特殊的委托 ;
作用:它封装了委托类型的变量,使得:在类的内部,不管你声明它是public还是protected,它总是private 的。在类的外部,注册“+=”和注销“-=”的访问限定符与你在声明事件时使用的访问符相同
注意;
事件的触发应当由 发布事件的程序触发 而不是追加方法到事件上的程序触发;
实例
using System;
using System.IO;
namespace BoilerEventAppl
{
// boiler 类
class Boiler
{
private int temp;
private int pressure;
public Boiler(int t, int p)
{
temp = t;
pressure = p;
}
public int getTemp()
{
return temp;
}
public int getPressure()
{
return pressure;
}
}
// 事件发布器
class DelegateBoilerEvent
{
public delegate void BoilerLogHandler(string status);
// 基于上面的委托定义事件
public event BoilerLogHandler BoilerEventLog;
public void LogProcess()
{
string remarks = "O. K";
Boiler b = new Boiler(100, 12);
int t = b.getTemp();
int p = b.getPressure();
if(t > 150 || t < 80 || p < 12 || p > 15)
{
remarks = "Need Maintenance";
}
OnBoilerEventLog("Logging Info:\n");
OnBoilerEventLog("Temparature " + t + "\nPressure: " + p);
OnBoilerEventLog("\nMessage: " + remarks);
}
protected void OnBoilerEventLog(string message)
{
if (BoilerEventLog != null)
{
BoilerEventLog(message); //触发事件
}
}
}
// 该类保留写入日志文件的条款
class BoilerInfoLogger
{
FileStream fs;
StreamWriter sw;
public BoilerInfoLogger(string filename)
{
fs = new FileStream(filename, FileMode.Append, FileAccess.Write);
sw = new StreamWriter(fs);
}
public void Logger(string info)
{
sw.WriteLine(info);
}
public void Close()
{
sw.Close();
fs.Close();
}
}
// 事件订阅器
public class RecordBoilerInfo
{
static void Logger(string info)
{
Console.WriteLine(info);
}//end of Logger
static void Main(string[] args)
{
BoilerInfoLogger filelog = new BoilerInfoLogger("e:\\boiler.txt");
DelegateBoilerEvent boilerEvent = new DelegateBoilerEvent();
boilerEvent.BoilerEventLog += new
DelegateBoilerEvent.BoilerLogHandler(Logger);
boilerEvent.BoilerEventLog += new
DelegateBoilerEvent.BoilerLogHandler(filelog.Logger);
boilerEvent.LogProcess();
Console.ReadLine();
filelog.Close();
}//end of main
}//end of RecordBoilerInfo
}
特性
概念: 特性 是用于在运行是传递程序中的各种元素(比如 类,方法,结构,枚举,组件等)的行为信息的声明性标签;您可以通过使用特性向程序添加声明性信息。一个声明性标签是通过放置在它所应用的元素前面的方括号([ ])来描述的。
语法:[attribute(positional_parameters, name_parameter = value, …)]
element
匿名方法
概念: 匿名方法提供了一种传递代码块作为委托参数的技术;匿名方法只有方法主体,没有方法名称,匿名方法可以不指定返回类型,返回类型可以通过return语句自行进行推断出来; 简单理解就是没有名字的方法;
lamda表达式既是匿名方法的进化版
LambdaClass lc = new LambdaClass();
//初始状态
//LambdaClass.SayHandler hander1 实例化委托
LambdaClass.SayHandler hander1 = new LambdaClass.SayHandler(
delegate(string name, int age) { }
);
//进化1
LambdaClass.SayHandler hander2 = delegate(string name, int age) { };
//进化2 delegate去掉后 换上了一个新的符号 gose to =>
LambdaClass.SayHandler hander3 = (string name, int age) => { Console.WriteLine("你好"); };
//进化3
LambdaClass.SayHandler hander4 = (x, y) => { Console.WriteLine("你好"); };
//进化4 如果匿名方法中只有一行代码 那么花括号可以省略
LambdaClass.SayHandler hander5 = (x, y) => Console.WriteLine("你好");
hander5("张三", 18);
文件操作
文件操作使用较少,后期将会继续补充
异常
异常是程序执行期间出现的问题;C#中的异常是对程序运行时出现特殊情况的一种响应;
异常处理关键字: try、catch、finally 和 throw。
try:一个 try 块标识了一个将被激活的特定的异常的代码块。后跟一个或多个 catch 块。
catch:程序通过异常处理程序捕获异常。catch 关键字表示异常的捕获。
finally:finally 块用于执行给定的语句,不管异常是否被抛出都会执行。例如,如果您打开一个文件,不管是否出现异常文件都要被关闭。
throw:当问题出现时,程序抛出一个异常。使用 throw 关键字来完成。
异常使用部位,一些在程序中无法欲测到地方,例如数据库读写,网络请求,远程接口调用等
使用案例
try
{
// 引起异常的语句
}
catch( ExceptionName e1 )
{
// 错误处理代码
}
catch( ExceptionName e2 )
{
// 错误处理代码
}
catch( ExceptionName eN )
{
// 错误处理代码
}
finally
{
// 要执行的语句
}
在这里我们需要留意的是,特殊的异常向上排列,越大众的异常越向下排列