幕后的C#lambda
对于没有使用经验的人来说,以下代码让它看起来很神奇:幕后的C#lambda,c#,lambda,C#,Lambda,对于没有使用经验的人来说,以下代码让它看起来很神奇: int totalScore = File.ReadLines(@"c:/names.txt") .OrderBy(name => name) .Select((name, index) => { int score = name.AsEnumerable().Select(character => character - 9
int totalScore = File.ReadLines(@"c:/names.txt")
.OrderBy(name => name)
.Select((name, index) => {
int score = name.AsEnumerable().Select(character => character - 96).Sum();
score *= index + 1;
return score;
})
.Sum();
是什么使名称引用集合中的元素,更有趣的是,是什么使索引引用元素的索引
因为这显然不是一个魔术,除了理解(可能还有其他什么?)之外,Lambda表达式是如何工作的?这实际上与lambdas无关,您可以同样轻松地向它传递一个方法,该方法使用字符串和
int
参数。您可以编写自己的select实现:
public static class TestClass
{
public static IEnumerable<TReturnType> DoSelect<TSourceType, TReturnType>(this IEnumerable<TSourceType> source, Func<TSourceType, int, TReturnType> action)
{
int i = 0;
foreach(var row in source)
yield return action(row, i++);
}
}
您也可以在不使用lambdas的情况下为select编写代码:
private int MyFunction(string name, int index)
{
int score = name.AsEnumerable().Select(character => character - 96).Sum();
score *= index + 1;
return score;
}
int totalScore = File.ReadLines(@"c:/names.txt")
.OrderBy(name => name)
.Select(MyFunction)
.Sum();
没有魔法,所有的
Select
都在执行
public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, int, TResult> selector) {
if (source == null) throw Error.ArgumentNull("source");
if (selector == null) throw Error.ArgumentNull("selector");
return SelectIterator<TSource, TResult>(source, selector);
}
static IEnumerable<TResult> SelectIterator<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, int, TResult> selector) {
int index = -1;
foreach (TSource element in source) {
checked { index++; }
yield return selector(element, index);
}
}
这和
private int SomeFunction(string name, int index)
{
int score = name.AsEnumerable().Select(character => character - 96).Sum();
score *= index + 1;
return score;
}
因此,Select
传入name
和index
值,并调用您的函数
public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, int, TResult> selector) {
if (source == null) throw Error.ArgumentNull("source");
if (selector == null) throw Error.ArgumentNull("selector");
return SelectIterator<TSource, TResult>(source, selector);
}
static IEnumerable<TResult> SelectIterator<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, int, TResult> selector) {
int index = -1;
foreach (TSource element in source) {
checked { index++; }
yield return selector(element, index);
}
}
(name, index) => {
int score = name.AsEnumerable().Select(character => character - 96).Sum();
score *= index + 1;
return score;
}
private int SomeFunction(string name, int index)
{
int score = name.AsEnumerable().Select(character => character - 96).Sum();
score *= index + 1;
return score;
}