约束类型包括基类约束、构造函数约束、接口约束、参数约束等。如:
public class FateherTest
{
}
//where的用法 接口约束IComparable 和构造函数约束new(), 基类约束 FatherTest
public class TestA where T : FateherTest, IComparable, new()
{
}
public class TestB
{
//限制传递参数的类型必须继承IComparable 参数类型约束
public int Caculate(T t) where T : IComparable
{
throw new NotImplementedException();
}
}
二、集合条件查询
1.使用方法
List2.如何实现的list = new List (); //返回b.value的值 ==2的 IEnumerable对象 list.Where((b) => b.value == 2).ToList(); Dictionary dic = new Dictionary (); //TSource是 KeyValuePair dic.Where((b) => b.Value.value== 2);
在System.linq命名空间下的Enumerable类里面实现了IEnumerable的扩展方法.如下:
//返回值是IEnumerable迭代器对象 public static IEnumerable Where ( this IEnumerable source, Func predicate) { if (source == null) throw Error.ArgumentNull(nameof (source)); if (predicate == null) throw Error.ArgumentNull(nameof (predicate)); switch (source) { case Enumerable.Iterator _: return ((Enumerable.Iterator ) source).Where(predicate); case TSource[] _: return (IEnumerable ) new Enumerable.WhereArrayIterator ((TSource[]) source, predicate); case List _: return (IEnumerable ) new Enumerable.WhereListIterator ((List ) source, predicate); default: return (IEnumerable ) new Enumerable.WhereEnumerableIterator (source, predicate); } }
当我们调用List.Where扩展方法时返回了一个WhereListIterator对象:
reurn (IEnumerable
我们可查看 WhereListIterator 这个类,它继承了:Enumerable.Iterator
public override bool MoveNext()
{
if (this.state == 1)
{
while (this.index < this.source.Length)
{
TSource source = this.source[this.index];
++this.index;
if (this.predicate(source))
{
this.current = source;
return true;
}
}
this.Dispose();
}
return false;
}
只有通过predictate的检测之后MoveNext才会返回true.调用Tolist的时候回调用 IEnumrable的扩展方法Tolist 调用创建一个List
[__DynamicallyInvokable] public List(IEnumerablecollection) { if (collection == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection); if (collection is ICollection objs) { int count = objs.Count; if (count == 0) { this._items = List ._emptyArray; } else { this._items = new T[count]; objs.CopyTo(this._items, 0); this._size = count; } } else { this._size = 0; this._items = List ._emptyArray; foreach (T obj in collection) this.Add(obj); } }
上面使用foreach会调用WhereListIterator 的MoveNext.直到返回false结束。而上面的MoveNext用来Func委托函数做筛选。
我们还可以做如下操作:
var whereListIt = list.Where((b) => b.value >1) Funcfunc = delegate (InstanceB b) { b.value = 3; return b; }; newList = whereListIt.Select(func).ToList();
筛选出第一次b.value >1的独享 第二次将筛选对象的value都设置为3.
public override bool MoveNext()
{
if (this.state == 1)
{
while (this.index < this.source.Length)
{
TSource source = this.source[this.index];
++this.index;
if (this.predicate == null || this.predicate(source))
{
//这里可以看出Selector是对source进行操作,并不是筛选。
this.current = this.selector(source);
return true;
}
}
this.Dispose();
}
return false;
}
几个类结构如下:
- WhereListIterator:Enumerable.Iterator
:IEnumerable - WhereListIterator:Enumerable.Iterator
:IEnumerable
所以有连续的操作如:
list.Where((b) => b.value == 2).where((b) => b.value == 2) Funcfunc = delegate (InstanceB b) { b.value = 3; return b; }; list.Select(t).Select(t)
也可以有组合的操作
list.Where((b) => b.value == 2).Select(t) 原因是连续操作内部做了 Combine操作:下面是Selector调用Selector即:Selector.Selector public override IEnumerableSelect ( Func selector) { return (IEnumerable ) new Enumerable.SelectEnumerableIterator (this._source, Enumerable.CombineSelectors (this._selector, selector)); } 组合操作做了组合:下面是Selector.Where的组合操作 public override IEnumerable Where(Func predicate) => (IEnumerable ) new Enumerable.WhereEnumerableIterator ((IEnumerable ) this, predicate);
/组合操作时会把This当前对象传递到下个对象WhereEnumerableIterator。而WhereEnumerableIterator在MoveNext中的操作如下:
- 取了上个对象的迭代器,先做处理。
- 调用了上个对象的MoveNext对Selector的Func进行了调用,之后再调用this.predicate做筛选。
对于List、Dictionary和Array
- 使用扩展方法扩展扩展IEnumrable的功能,而不修改IEnurable接口内容。
- 实现新的类对象,持有IEnumrable对象做迭代处理,使用的是组合的方式而不是继承的方式。
- 新创建的对象分别代表不同的操作,继承同一个父类,因此不同对象之间使用组合模式可以相互组合,实现复杂的操作。
现在又要给这些数据集合添加功能是筛选.实现方法有以下两种:
1.新写一个接口让这些集合实现,利用迭代的功能实现筛选。坏处是某个对象都需要实现这个方法。破坏了原有类的结构。
2.由于筛选功能只是用到了迭代器,因此可以:
- 使用扩展方法扩展扩展IEnumrable的功能,而不修改IEnurable接口内容。
- 实现新的类对象,持有IEnumrable对象做迭代处理,使用的是组合的方式而不是继承的方式。
- 新创建的对象分别代表不同的操作,继承同一个父类,因此不同对象之间使用组合模式可以相互组合,实现复杂的操作。



