Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/actionscript-3/7.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
C# 3.0 _C# 3.0_Lambda - Fatal编程技术网

C# 3.0

C# 3.0 ,c#-3.0,lambda,C# 3.0,Lambda,可枚举。其中循环列表并创建一个新列表,该列表仅包含所提供函数返回true的元素。这样,您就不用编写代码来遍历列表、检查每个元素的谓词并执行某些操作。我了解lambdas基础知识的技巧有两个方面 首先,我建议学习函数式编程。在这方面,Haskell是一种很好的语言。我正在使用的这本书是格雷厄姆·赫顿写的,从中受益匪浅。这为Haskell打下了良好的基础,包括对lambdas的解释 从这里开始,我认为您应该看到,他们也对函数式编程进行了很好的介绍,还使用了Haskell,并过渡到了C 一旦您了解了所

可枚举。其中循环列表并创建一个新列表,该列表仅包含所提供函数返回true的元素。这样,您就不用编写代码来遍历列表、检查每个元素的谓词并执行某些操作。

我了解lambdas基础知识的技巧有两个方面

首先,我建议学习函数式编程。在这方面,Haskell是一种很好的语言。我正在使用的这本书是格雷厄姆·赫顿写的,从中受益匪浅。这为Haskell打下了良好的基础,包括对lambdas的解释

从这里开始,我认为您应该看到,他们也对函数式编程进行了很好的介绍,还使用了Haskell,并过渡到了C


一旦您了解了所有这些,您就应该能够很好地理解lambdas了。

让我们剖析一下您的代码示例:

filenames.SelectMany(f => 
        Assembly.LoadFrom(f).GetCustomAttributes(typeof(PluginClassAttribute), true)
        .Cast<PluginClassAttribute>()
        .Select(a => a.PluginType)
).ToList();
SelectMany
将委托作为参数,在这种情况下,委托必须将类型为
string
的一个参数作为输入,并返回
IEnumerable
(其中
T
的类型是推断的)。这就是Lambda进入舞台的地方:

filenames.SelectMany(f => 
        Assembly.LoadFrom(f).GetCustomAttributes(typeof(PluginClassAttribute), true)
).ToList()
这里将发生的是,对于
filenames
数组中的每个元素,都将调用委托
f
是输入参数,
=>
右边的任何内容都是委托引用的方法体。在这种情况下,将为数组中的文件名调用
Assembly.LoadFrom
,使用
f
参数将文件名传递给
LoadFrom
方法。在返回的
AssemblyInstance
上,将调用
GetCustomAttributes(typeof(PluginClassAttribute),true)
,它返回一个
Attribute
实例数组。因此编译器无法推断前面提到的
T
类型是
Assembly

在返回的
IEnumerable
上,将调用
Cast()
,返回一个
IEnumerable

现在我们有了一个
IEnumerable
,我们在上面调用
Select
Select
方法类似于
SelectMany
,但返回类型为
T
(由编译器推断)的单个实例,而不是
IEnumerable
。设置相同;对于
IEnumerable
中的每个元素,它将调用已定义的委托,并将当前元素值传递给它:

.Select(a => a.PluginType)
同样,
a
是输入参数,
a.PluginType
是方法主体。因此,对于列表中的每个
PluginClassAttribute
实例,它将返回
PluginType
属性的值(我将假定此属性属于
类型

执行摘要
如果我们把这些碎片粘在一起:

// process all strings in the filenames array
filenames.SelectMany(f => 
        // get all Attributes of the type PluginClassAttribute from the assembly
        // with the given file name
        Assembly.LoadFrom(f).GetCustomAttributes(typeof(PluginClassAttribute), true)
        // cast the returned instances to PluginClassAttribute
        .Cast<PluginClassAttribute>()
        // return the PluginType property from each PluginClassAttribute instance
        .Select(a => a.PluginType)
).ToList();
这是最常见的方法;使用lambda表达式设置它。但也有其他选择:

Func<string,bool> func = delegate(string s) { return s.StartsWith("t");};
result = strings.Where(func);
因此,在我们这里看到的例子中,lambda表达式是定义委托的一种相当紧凑的方式,通常引用匿名方法


如果你有足够的精力在这里阅读,那么,谢谢你的时间:)

一个很好的简单解释是,TekPub上的这个简单的视频,针对那些对编码非常熟悉但对lambdas不熟悉的开发人员


显然,这里有很多反馈,但这是另一个很好的来源和简单的解释。

CodeProject最近有一篇很好的介绍性文章:

我知道这有点老了,但我来这里是为了理解所有这些lambda的东西。 当我把所有的答案和评论都翻了一遍之后,我对lambda有了更好的理解,我想我应该添加这个简单的答案(从学习者的角度来看):

不要混淆
a=>a+1
的意思是将1添加到a并将结果返回到a。(这很可能是初学者困惑的根源。 而是这样看:a是函数的输入参数(未命名函数),a+1是函数中的语句(未命名函数“动态构造”)


希望这有帮助:)

基本上,lambda与任何其他函数都一样,只是它们是在需要的地方定义的。你熟悉匿名类吗?他们这样做只是为了方法。(作为评论发布,因为我不希望达到其他答案的质量)我将无耻地插入Jon Skeet的引用:这实际上有助于提高我对lambda表达式的理解。很好的阅读,当然!!!我强烈建议您访问Lambdaexpression.net只是随机地重新访问一下。。。如果您现在还没有弄明白这一点-您不需要在您发布的lambda中进行“==true”检查。它可以简单地通过执行“start=>start.IsBatch”来表示,因为IsBatch本身是一个布尔值。@kastermester:当然,今天我会用不同的方式来写;)。。。我很高兴看到这个问题和出色的答案帮助了很多人。@Fredrik mörk:非常好的解释,感谢你在“图解”陈述中的帮助。当你不懂速记版本的时候,这是很吓人的。在你和Kastermester之间,我想我得到了这个…这不是火车!!!再次感谢你!这是对我们其他人似乎忽视的一个实际问题的一个很好的回答——干得好!好极了这正是我需要的解释。谢谢你花时间写这篇文章@卡斯特:谢谢你的解释。我想有一件事让我感到不舒服,那就是推断出的参数“类型”。干得好!!不客气,很高兴我能帮上忙。在C#代码中最初几次遇到它们时,很难理解它们——一旦你理解了,它们可以让很多东西变得更简单——而且它们非常有用,不仅仅是与LINQ.+1个漂亮的视频剪辑结合使用……我的声音坏了:(我得到了
private int sum5(int n)
{
    return n + 5;
}
...methodbody
int acc = 5;
Func<int> addAcc = (n) => n + acc;
IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector);
string MyConcat(string str){
    return str + str;
}

...

void myMethod(){
    IEnumerable<string> result = someIEnumerable.Select(MyConcat);
}
void myMethod(){
    IEnumerable<string> result = someIEnumerable.Select(s => s + s);
}
void myMethod(){
    IEnumerable<string> result = someIEnumerable.Select((string s) => s + s);
}
a => a + 1
List<string> fruits = new List<string> { 
        "apple", "passionfruit", "banana", "mango", 
        "orange", "blueberry", "grape", "strawberry" };

IEnumerable<string> shortFruits = fruits.Where(fruit => fruit.Length < 6);

foreach (string fruit in shortFruits) {
    Console.WriteLine(fruit);
}
filenames.SelectMany(f => 
        Assembly.LoadFrom(f).GetCustomAttributes(typeof(PluginClassAttribute), true)
        .Cast<PluginClassAttribute>()
        .Select(a => a.PluginType)
).ToList();
filenames.SelectMany(
   ...
).ToList();
filenames.SelectMany(f => 
        Assembly.LoadFrom(f).GetCustomAttributes(typeof(PluginClassAttribute), true)
).ToList()
.Select(a => a.PluginType)
// process all strings in the filenames array
filenames.SelectMany(f => 
        // get all Attributes of the type PluginClassAttribute from the assembly
        // with the given file name
        Assembly.LoadFrom(f).GetCustomAttributes(typeof(PluginClassAttribute), true)
        // cast the returned instances to PluginClassAttribute
        .Cast<PluginClassAttribute>()
        // return the PluginType property from each PluginClassAttribute instance
        .Select(a => a.PluginType)
).ToList();
List<string> strings = new List<string> { "one", "two", "three" };
var result = strings.Where(s => s.StartsWith("t"));
Func<string,bool> func = delegate(string s) { return s.StartsWith("t");};
result = strings.Where(func);
private bool StringsStartingWithT(string s)
{
    return s.StartsWith("t");
}

// somewhere else in the code:
result = strings.Where(StringsStartingWithT);