回字的4种写法:
Enumerable.Aggregate 扩展方法在System.Linq命名空间中,是Enumerable类的第一个方法(按字母顺序排名),但确是Enumerable里面相对复杂的方法。
1. Aggregate 累加器函数 1.1. 值类型实现int Sum = listItem.Aggregate((i, j) => i + j);
Console.WriteLine($"Sum:{Sum}");
Console.WriteLine($"值列表:{string.Join(",", listItem)}");
1.2. 引用类型错误使用
int Sum = listItem.Aggregate((i, j) => i + j);
Console.WriteLine($"Sum:{Sum}");
Console.WriteLine($"值列表:{string.Join(",", listItem)}");
//引用问题
int SumAge = listStudentItem.Aggregate((i, j) =>
{
i.Age += j.Age;
return i;
}).Age;
Console.WriteLine($"SumAge:{SumAge}");
Console.WriteLine($"引用列表Error使用:{string.Join(",", listStudentItem)}");
1.3 到这里我们来看一下Aggregate函数的源代码
public static partial class Enumerable
{
public static TSource Aggregate(this IEnumerable source, Func func)
{
if (source == null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source);
}
if (func == null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.func);
}
using (IEnumerator e = source.GetEnumerator())
{
if (!e.MoveNext())
{
ThrowHelper.ThrowNoElementsException();
}
TSource result = e.Current;
while (e.MoveNext())
{
result = func(result, e.Current);
}
return result;
}
}
}
主要由于“TSource result = e.Current;” 如果是引用类型时将会修改引用类型的值。
1.4 引用类型的正确使用int Sum = listItem.Aggregate((i, j) => i + j);
Console.WriteLine($"Sum:{Sum}");
Console.WriteLine($"值列表:{string.Join(",", listItem)}");
//引用问题
int SumAge = listStudentItem.Aggregate((i, j) =>
{
i.Age += j.Age;
return i;
}).Age;
Console.WriteLine($"SumAge:{SumAge}");
Console.WriteLine($"引用列表Error使用:{string.Join(",", listStudentItem)}");
InitAggregate();
//没有引用问题
SumAge = listStudentItem.Aggregate(0, (i, j) =>
{
i += j.Age;
return i;
});
Console.WriteLine($"SumAge:{SumAge}");
Console.WriteLine($"引用列表:{string.Join(",", listStudentItem)}");
源代码如下:
public static partial class Enumerable
{
public static TAccumulate Aggregate(this IEnumerable source, TAccumulate seed, Func func)
{
if (source == null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source);
}
if (func == null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.func);
}
TAccumulate result = seed;
foreach (TSource element in source)
{
result = func(result, element);
}
return result;
}
}
1.5 Aggregate实现Where().Sum()
private void btnAggregateEqWhereSum_Click(object sender, EventArgs e)
{
int SumAge = listStudentItem.Where((item,index)=>index%2==0).Sum(a => a.Age);
Console.WriteLine($"SumAge:{SumAge}");
Console.WriteLine($"引用列表:{string.Join(",", listStudentItem)}");
int Sum = listStudentItem.Aggregate(0,(inObj,item,index) =>
{
if (index % 2 == 0)
{
inObj += item.Age;
}
return inObj;
});
Console.WriteLine($"Sum:{Sum}");
Console.WriteLine($"引用列表:{string.Join(",", listStudentItem)}");
}
public static class AggregateExpaned
{
public static TAccumulate Aggregate(this IEnumerable source, TAccumulate seed, Func func)
{
int index = 0;
using (IEnumerator enumerator = source.GetEnumerator())
{
TAccumulate result = seed;
while (enumerator.MoveNext())
result = func(result, enumerator.Current, index++);
return result;
}
}
}
1.5.1 Where源代码
public static IEnumerableWhere (this IEnumerable source, Func predicate) { if (source == null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source); } if (predicate == null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.predicate); } return WhereIterator(source, predicate); } private static IEnumerable WhereIterator (IEnumerable source, Func predicate) { int index = -1; foreach (TSource element in source) { checked { index++; } if (predicate(element, index)) { yield return element; } } }



