c#基础
1。协变逆变
协变逆变用于接口和委托的泛型参数的一组关键字, out 和 in
协变: I<out object> = I<sting>
逆变: I<in string> = I<objet>
ps。泛型实例并不存在继承关系
ps。本质都是调用实例算法。协变接口是开放的,只要实现子类参数的定义,就可以调用特例算法;逆变接口是封闭的,只能向上调用父类参数的算法。
协变逆变不支持值类型参数,不支持ref,out函数形参,不支持作为接口方法的泛型约束。该接口不能嵌套类,枚举或结构。
协变的参数只能用来做方法的返回类型,逆变的参数只能用作方法的参数类型。
协变逆变只是限定当前指定对象,不通过继承来传递特性。
定义格式:
interface I<in A, out R>
2。关键接口
IEnumerable<out T> : 支持简单迭代的集合。该接口只是返回IEnumerator<out T>。
IEnumerator<T> GetEnumerator()
IEnumerator<out T>:IDisposable ,
Dispose()
bool MoveNext() :枚举下一个元素,超过尾部为false
Reset() :只用在com对象。
T Current: 当前位置元素,第一次MoveNext()之后为第一个元素。
IQueryable<out T>:IEnumerable<T> ,支持不同数据源查询的类型。
IEnumerator<T> GetEnumerator()
Type ElementType : 元素类型
Expression Expression : 表达式目录树
IQueryProvider Provider : 创建IQueryable实例的提供程序
IGrouping<out TKey, out TElement> : IEnumerable<TElement> ,表示具有公共键的集合。
IEnumerator<TElement> GetEnumerator()
TKey Key : 键
IComparer<in T> : 比较算法
int Compare(T,T) :负值小于,零等于,正值大于,null小于任何引用
IEqualityComparer<in T> : 相等性算法
bool Equals(T,T)
int GetHashCode(T) : 若两对象相等,hash必然相等
IComparable<in T>: 可比较的对象
int CompareTo(T)
IEquatable<in T> : 可比较相等的对象
bool Equals(T)
发现一个规律(不懂英文的人飘过),able结尾的指的是一个对象去实现这个接口,让它自身具备某种特性。而er之类结尾的,是作为一个参数传递给特定方法调用,用来制定所使用的算法。
3。关键委托
Action<in T> : void (T)
Action<in T1, in T2> : void (T1, T2)
Func<out TResult>: TResult ()
Func<in T,out TResult>: TResult (T)
Predicate<in T>: bool (T) , 参数是否符合条件
Comparison<in T>: int (T, T), 比较算法,和IComparer<in T>的分别是这个是委托,不是对象.
Converter<in TInput, out TOutput>: TOutput (TInput), 转换算法
4.LINQ 语言集成查询
linq三步曲:获取数据源、创建查询、执行查询。
linq支持查询IEnumerable<out T> 接口的任意对象。
linq支持创建对数据源进行联接、筛选、排序,分组、映射(结构化)的查询。
linq语言要素:
from :指定数据源,格式: from 范围变量 in 数据源
数据源:任意实现IEnumerable<out T>的对象
范围变量:可以用 let 字句添加新的范围变量,范围变量只能有一个值或一个表达式定义(可包含另一个范围变量)。
join : 等同联接,对没有显式建模的序列建立关联;两个序列需要可以共享可以判断是否相等的项;格式:from x in X join y in Y on x.ID equals y.ID
join 只支持同等联接,但有三个形式:内部联接,分组联接,左外部联接。
内部联接:第一个集合的元素匹配第二个集合每一个元素,如果第二个集合没有匹配就不产生结果,有n个匹配项就有n条结果。
into 子句:分组联接,让内部联接的结果类似分组结果,但没有键,本质是多组的序列集合。第一个集合的元素个数为组的个数,第二个集合的匹配项是改组的元素。
.DefaultIfEmpty (defaultObj) : 当匹配为空时,也就是空序列,调用该函数产生有一个默认元素的序列。这个就是左外部联接,基于分组联接,格式: join…into G from g in G.DefaultIfEmpty(…)
非等同联接:多个from 引入数据源,达到交叉联接的结果;低效率,但是支持let 引入范围变量,支持菲等同联接。
where :筛选器,格式:where 条件表达式
orderby : 排序,对结果集进行排序,ascending 升序, descending 降序,格式:orderby 返回序列所指定的排序器 ascending
group: 分组,按指定键对序列分组,格式:group 返回的序列 by 分组的键
into: 可以用来定义分组结果的范围变量,以便继续操作该结果,格式: group x by x.key into xGroup。
select : 映射到结果集
ps。组合键:用多个键来定义匹配,键匹配取决属性名称及顺序,但可以分配新名字。
执行查询:
linq变量只是保存查询命令,而具体的查询操作通过foreach 等语句和相关函数。
ToList<TSource>() : 返回List包装的结果集
ToArray<TSource(): 返回Array包装的结果集
第二类是聚合函数(也就是返回单个值):
Count() : 统计结果集条目数
Max() :
Average() : 求序列平均值
First() : 返回结果集的首条内容
……
ps。每个IEnumerable<out T> 对象本身理论上可能只能查询一次。
linq 之外的集合操作:
标准linq只有联接、筛选、排序、分组、映射五种操作,因此有些对集合的操作用linq很难实现。
聚合函数:
实现以下功能:元素存在性判断,集合是否相等,聚合特征值(最大值,最小值,平均值,个数,总和),提取指定元素
predicate : Func<T,bool>
comparer: IEqualityComparer<T>
coverter : Func<TInput, TOutput>
S : IEnumerable<T>
bool All(predicate) : 集合所有元素是否满足条件,空集合返回true
bool Any() :如果包含元素返回true
bool Any(predicate) : 包含满足条件的元素返回true
bool Contains(T) : 判断序列是否有给定元素,使用Default相等比较器
bool Contains(T, comparer) :同上,指定比较器
bool SequenceEqual(S) : 比较两序列是否相等
bool SequenceEqual(S, comparer) : 同上,用指定比较器
T Aggregate(Func<T 聚合,T 元素,T 聚合>) :通过迭代自定义聚合
X Aggregate(X 聚合, Func<X 聚合, T 元素, X 聚合>):同上,指定聚合变量
X Aggregate(X, Func<X,T,X>, coverter) : 同上,添加最终聚合的转换函数
T Average(): 序列平均值,空集合异常
X Average(coverter): 指定转换函数,求平均值 ,空集合异常
int Count() : 序列元素个数,更大范围的对应函数:long LongCount()
int Count(predicate) : 满足条件的元素个数
X Max() : 返回序列中最大的元素,空集合异常,使用IComparable<T>比较接口
X Max(coverter) : 指定转换函数,返回序列最大的元素
X Min() : 序列最小元素
X Min(coverter):
X Sum() : 序列和
X Sum(coverter) : 经过转换的序列和
T ElementAt(int) : 返回自定位置的元素
T ElementAtOrDeflault(int) : 同上,超出范围返回默认值
T First() : 序列第一个元素
T First(predicate): 符合条件的第一个元素
T FirstOrDefault() :返回第一个元素,如无返回默认值
T FirstOrDefault(predicate): 返回符合条件的第一个元素,如无返回默认值
T Last() : 返回序列最后一个元素
T LastOrDefault() : 同上,如无返回默认值
T Last(predicate):
T LastOrDefault():
T Single(): 返回序列唯一的一个元素
T Single(predicate): 返回序列唯一符合条件的一个元素
T SingleOrDefault():如果序列为空返回默认值
T SingleOrDefault(predicate): 如果都不符合条件,返回默认值
集合转换:
实现以下功能:串联,集合操作(差,并,交),去除重复元素,反转序列,抽取序列段落,生成或者转换序列
S : IEnumerable<T>
predicate : Func<T,bool>
comparer: IEqualityComparer<T>
S Concat(S): 串联两个序列
S Distinct() : 返回不重复元素组成的序列。通过EqualityComparer<T>.Default相等比较器
S Reverse() : 返回反转元素顺序的序列。
S Except(S) : 返回第一个集合和第二个集合的集合差。该操作不符合交换率,通过Default相等比较器
S Except(S, comparer) :同上,指定比较器
S Intersect(S) : 返回两集合的交集(两集合共有的元素,并去除重复元素),使用Default比较器
S Intersect(S, comparer): 同上,指定比较器
S Union(S) : 返回两集合的并集(合集,但去除重复元素),使用Default比较器。
S Union(S,comparer):同上,指定比较器
S Skip(int) : 跳过前n个元素,返回剩余序列
S SkipWhile(predicate) : 跳过满足条件的元素,直到遇到不满足的首个元素,返回剩余序列
S SKipWhile(Func<T, int, bool>) : 同上,但传入元素位置给条件函数
S Take(int) : 返回前n个元素组成的序列
S TakeWhile(predicate) : 返回满足条件的元素组成的序列,直到遇到首个不满足的元素。
S TakeWhile(Func<T,int,bool>) :同上,传入元素位置给条件函数
S DefaultIfEmpty() : 返回非空集
S DefaultIfEmpty(T): 返回非空集,指定元素默认值
S Empty() :返回空集
S Range(int start, int count) : 生成指定范围的整数序列
S Repeat(T, int count): 生成指定个数的重复元素的序列
S AsEnumerable() : 返回基类实现
IQueryable<T> AsQueryable() : 返回IQueryable查询接口
S OfType() : 转化为指定类型的序列,如不能转换的元素自动忽略
T[] ToArray() : 转化为数组
List<T> ToList():转化为List
Dictionary<TKEY,TValue> ToDictionary(……) :转化为字典
Lookup<TKey, TElement> ToLookup(……) :转化为键组合结构序列
5。面向对象
抽象数据类型定义:通过字段将若干类型按照一定语义组合在一起,形成一个单一类型的方法。
对象:基于抽象数据类型,但对外部操作行为进行限制和干预,形成一个具有自主权意识的对象类型。
面向对象:不直接操作对象,而基于接口界面操作对象。
对象设计的思想是:保持自主权,减少外界干预,可以保持个体的正确性,而个体的正确性,保证了系统的正确性。
面向对象设计的思想是:对象对外界的依赖,应该通过接口隔离,当一个外部对象失效的时候,可以通过相同的界面访问新的对象。
对象设计是基于内部的视角,核心内容是保持自身的正确性,和语义上的内聚性;而面向对象是基于外部的视角,核心内容是降低对象间的耦合度。
面向对象语法要素:
字段: 为实现语义所需要的数据片段
属性: 可控的字段
方法: 可控操作界面,参数化控制对象状态
构造函数: 对象的初始化
析构函数: 对象的析构
事件: 对象的通信界面,参数化通信内容
委托: 委派任务给外部对象
嵌套类: 局部细化对象定义。
访问权限: 控制暴露到外界的界面
静态成员: 同类共享区域(建议不要暴露)
匿名类型:简单的抽象数据类型,只能临时用
接口: 规范化的操作界面(从使用者角度定义)
泛型参数:泛化基础类型的编程方法,但是每个实例都是强类型的。用于类、结构、接口和方法。
值类型和引用类型:结构和枚举是值类型,值类型以内联的方式分配,没有独立分配,所以是高性能的。
索引器:模仿数组的语法糖。
字段和属性的区别:
字段是不加限制的,属性是可控的,如果字段本身是无需控制的,那就可以用字段,否则应该隐藏字段,让属性作为操作界面。无需控制的含义在于它的取值范围等于类型的取值范围;它是独立,和其他字段无关和没有事务关联的;它不是只读或只写的。
接口:
接口可由方法、属性、事件、索引器组合而成。
索引器: T this[T1 index,…]{get;set;}
显式实现和隐式实现接口的差异:
1、显式实现的访问器需要匹配(set;get;) .
2、隐式实现需要公开成员
3、显式实现无法通过类实例访问,而需要转化为该接口来访问
4、显式实现的事件需要编写访问器(add;remove;)
5、显式实现格式:… 接口名.成员 …
委托和事件:
1、事件通过+= 添加订阅者,-=删除订阅者,无订阅者事件实例为null
2、标准事件基于EventHandler<T>委托:void (object sender, T e) where T:EventArgs
3、可以自定义事件访问器,格式:
add { lock(事件字段) {…}} //防止线程问题
remove{lock(事件字段){…}}
4、静态事件sender = null ,非静态sender不为空。e 不应为空,可用EventArgs.Empty代替
5、引发事件和处理事件默认是同步的,同时事件处理可能引发未处理的一样,导致程序崩溃
6、事件和委托的关系类似属性和字段的关系。只是事件相对属性而言,只支持+= 和-=操作而不是赋值和读取操作。
7、显式的事件(带访问器的)不会自动生成对应的委托和对应的访问器。
泛型:
可泛型化的对象:接口、类、方法、事件、委托。
泛型约束提供泛型约束的同时也提供了同等的能力,约束和能力是相互的。
泛型参数是引用时只会有一份代码,而根据不同值类型会产生对应的代码。
泛型所有代码版本逻辑上都是一致的,没有特列化。
约束:
where T:struct // 只能是值类型
where T:class // 只能是引用类型
where T:new() // 需要带默认构造函数
where T:基类或接口
where T:U //U也是泛型参数;T派生自U。
ps。约束告知编译器得以运用的操作。当约束为class,对象重载的==,!=运算符无效。
ps。无约束参数无法使用!=,==运算符,但可和null比较。
ps。default(T) 产生默认值,值类型为0,结构成员为0,引用为null
6。lambda
lambda表达式是匿名函数,可以用来创建委托或表达式树。
lambda语句(大括号包含的多行语句)无法用于创建表达式树。
例子:
()=>….
x=>…
(x,y)=>…
7。迭代器
迭代器是一个强大的语法糖:通过yield关键字立即返回迭代的当前项,产生一个嵌套类记录当前迭代的位置。迭代器方法最终返回IEnumerable<out T> 或IEnumerator<out T>对象。
迭代器是LINQ延迟查询的基础。
迭代器生成的嵌套类能够根据迭代器方法的内部语句生成对应的逻辑,因此它和手工写IEnumberable<out T>的相关实现效果是类似的,用户只需要根据yield的语义大胆使用便可。
ps.迭代器代码的效率不如手写代码。
语法:
yield break //终止迭代
yield return T //返回当前项
注意,不能顾名思义,这里的yield return并不是当前函数的返回(当前函数直接返回嵌套类对象),而是嵌套类的实现需要这个信息来设置枚举返回的项和需要在哪里暂停执行,哪里继续执行。每次枚举元素对应一次yield return:下一个枚举在这个语句后面继续执行,直到碰到下一个yield return才停止执行并返回当前元素。
8。集合和数据结构
.Net集合包含集中常用的数据结构:数组、列表(排序列表)、字典(哈希表)、队列,堆栈、包。
每一种集合,可能有几个不同特性的版本:线程安全的集合、已排序的集合、只读的集合。
线程安全的泛型版本:System.Collections.Concurrent
泛型版本:System.Collections.Generic
普通版本:System.Collections
各版本对应关系:
ArrayList 对应 List<T>
Hashtable 对应 Dictionary<TKey, TValue>、ConcurrentDictionary<TKey, TValue>
CollectionBase 对应 Collection<T>
ReadOnlyCollectionBase 对应 ReadOnlyCollection<T>
Queue 对应 Queue<T>、ConcurrentQueue<T>
Stack 对应Stack<T>、ConcurrentStack<T>
SortedList 对应SortedList<T>、ConcurrentSortedList<T>
无普通版的:
LinkedList<T>
SortedDictionary<TKey,TValue>
KeyedCollection<TKey,TItem>
BlockingCollection<T>
ConcurrentBag<T>
集合接口:
1.ICollection
2.IList、IDictionary
ps. 2继承1
ps。IDictionary的元素需要实现IComparer<T>大小比较器接口
ICollection 的实现:Queue、ConcurrentQueue<T>、Stack、ConcurrentStack<T>、LinkedList<T>、KeyedCollection<TKey,TItem>
IList 的实现:Array、ArrayList、List<T>
IDictionary 的实现:Hashtable、SortedList、Dictionary<TKey,TValue>、SortedList<TKey,TValue>、ConcurrentDictionary<TKey,TValue>
数学集合(元素不重复的集合):
ISet<T>
HashSet<T>
SortedSet<T>
位集合:
BitVector32
BitArray
其他集合:
StringCollection
StringDictionary
CollectionUtil
HybridDictionary
ListDictionary
NameValueCollection
NameObjectCollectionBase
BlockingCollection<T>
IProducerConsumerCollection<T>
ConcurrentBag<T>
9。文件和注册表
10。字符串和正则表达式
11。逻辑推理
主题:关于程序正确性的推理方法。
12。组合排列
主题:讨论如何穷举问题域。
13。三角函数
14。结构,算法,映射关系
主题:对于特定问题应该如何构建算法效率最高的数据结构。
待续……