约束类型包括基类约束、构造函数约束、接口约束、参数约束等。如:
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();
}
}
List 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(IEnumerable collection)
{
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)
Func func = 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;
}
几个类结构如下:
所以有连续的操作如:
list.Where((b) => b.value == 2).where((b) => b.value == 2)
Func func = 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 IEnumerable Select(
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中的操作如下:
对于List、Dictionary和Array
现在又要给这些数据集合添加功能是筛选.实现方法有以下两种:
1.新写一个接口让这些集合实现,利用迭代的功能实现筛选。坏处是某个对象都需要实现这个方法。破坏了原有类的结构。
2.由于筛选功能只是用到了迭代器,因此可以: