Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Lambda运算符如何工作以及它如何简化LINQ(c#)中的表达式?_C#_Linq_Expression - Fatal编程技术网

Lambda运算符如何工作以及它如何简化LINQ(c#)中的表达式?

Lambda运算符如何工作以及它如何简化LINQ(c#)中的表达式?,c#,linq,expression,C#,Linq,Expression,我是C#learning的新手,我不能清楚地理解lambda操作符,但我理解的是它简化了表达式 var testString = Console.ReadLine(); testString.ToCharArray() .OrderBy(i => i).ToLookup(j => j) .Select(i => new Program { letter = i.Key, count = i.Count()

我是C#learning的新手,我不能清楚地理解lambda操作符,但我理解的是它简化了表达式

 var testString = Console.ReadLine();
            testString.ToCharArray()
            .OrderBy(i => i).ToLookup(j => j)
            .Select(i => new Program { letter = i.Key, count = i.Count() }).ToList()
            .ForEach(i => Console.WriteLine("letter {0},count {1}", i.letter, i.count,i.sign));

在上面的代码中,我不了解'i'和'j'。这是一个匿名类型的变量还是对象?

问题是你的问题本身是错误的,你会问“这是一个变量还是对象还是匿名类型”,好像这三件事是不可接受的。匿名类型具有实例,这些实例是对象,引用这些对象的名称是变量。不过,我将尝试澄清语法,以便对您更有意义

要了解发生了什么,您必须了解所有这些奇特的linq运算符都有什么作为签名,让我们以OrderBy为例:

public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector);
现在,这种方法在大多数使用委托的情况下是有意义的,因为您必须指定所有这些信息(在不能使用类型推断的非泛型情况下)。但是,正如我之前所展示的,我们知道(由于推断),由于调用该函数的对象的类型,您从一开始就在处理Func,这意味着我们可以去除冗余信息,最终得到:

MyMethod(c)
{
   return c;
}
我们还能脱掉什么?好的,方法的名称!为什么?因为我们只使用它一次,所以如果它不被重用,为什么要命名它呢

(c) {返回c;}

另外,您经常希望做一些非常简单的事情,保存在一条语句中,那么为什么还要麻烦返回它呢?让我们隐式地返回语句的解析结果,并去掉括号! (c) c

现在我们只剩下一些与原始代码完全相同的东西(原始代码中的所有附加代码都是无用的,并且可以从上下文中推断出来,正如我所演示的),因此我们只需通过在输入变量和代码之间添加lambda操作符=>来更改语法,使其明显不同

(c) =>c

如果通过删除()只传入单个元素,则可以再次简化

c=>c

那么lambda接线员是什么?它是签名和代码之间的分隔符,整个表达式声明了一个while方法,而没有命名它,通过让编译器尽可能多地推断,在内联中以非常简洁的语法使用它。在您的例子中,i是一个局部变量,作为您正在内联定义的委托的输入传入


至于您在示例中没有使用的匿名类型,它们是内联声明的类型,没有命名,也可以在查询范围内使用(就像lambda表达式避免为不需要命名且不会重用的代码创建一次性函数一样,匿名类型避免为只使用一次的数据创建一次性类)。

…谢谢,我理解了它的含义,而且您的解释方式非常好。
public delegate TResult Func<in T, out TResult>(T arg)
char MyMethod(char c)
{
    return c;
}

bla.OrderBy(MyMethod); // This is a very verbose version, we defined an external method
MyMethod(c)
{
   return c;
}