C# lambda 表达式 - 将委托结果添加到通用列表
问题:我刚刚使用 C# lambda 表达式编写了第一个代码。 它有效,但我不确定这是否是最好的方法。 关于 lambda 表达式的更好方法有什么建议吗? 像我下面这样的表达式中有很多行代码似乎很奇怪。
背景:我有一份代表的通用名单。 每个委托函数都会返回一个枚举值,指示函数中发生的情况。 在评估委托时,如果枚举不是特定的枚举值,我需要将其添加到列表中。
免责声明:这里的代码非常通用,真正的代码实际上在委托中做一些事情来确定返回值!
class Class1
{
public enum WhatHappened
{
ThingA,
ThingB,
Nothing
}
private delegate WhatHappened del();
public static List<WhatHappened> DoStuff()
{
List<del> CheckValues = new List<del>();
List<WhatHappened> returnValue = new List<WhatHappened> { };
CheckValues.Add(delegate { return method1(); });
CheckValues.Add(delegate { return method2(); });
CheckValues.ForEach(x =>
{
WhatHappened wh = x();
if (wh != WhatHappened.Nothing)
returnValue.Add(wh);
});
return returnValue;
}
private static WhatHappened method1()
{
return WhatHappened.Nothing;
}
private static WhatHappened method2()
{
return WhatHappened.ThingA;
}
}
注意:我最初使用 lambda 来添加所有项目(见下文),然后删除我不想要的项目(WhatHappened.Nothing)。
CheckValues.ForEach(x => returnValue.Add(x()));
Question: I have just wrote my first code using c# lambda expressions. It works, but I am not sure if this is the best way to do it. Any recommendations on a better way to do the lambda expression? It seems odd to have numerous lines of code in the expression like I do below.
Background: I have a generic list of delegates. Each delegate function returns an enum value indicating what happened in the function. Upon evaluation of the delegate, I need to add the enum to a List if it was not a specific enum value.
Disclaimer: Code here is very generic, the real code actually does stuff in the delegates to determine the return value!
class Class1
{
public enum WhatHappened
{
ThingA,
ThingB,
Nothing
}
private delegate WhatHappened del();
public static List<WhatHappened> DoStuff()
{
List<del> CheckValues = new List<del>();
List<WhatHappened> returnValue = new List<WhatHappened> { };
CheckValues.Add(delegate { return method1(); });
CheckValues.Add(delegate { return method2(); });
CheckValues.ForEach(x =>
{
WhatHappened wh = x();
if (wh != WhatHappened.Nothing)
returnValue.Add(wh);
});
return returnValue;
}
private static WhatHappened method1()
{
return WhatHappened.Nothing;
}
private static WhatHappened method2()
{
return WhatHappened.ThingA;
}
}
Note: I originally had the lambda like adding all the items (see below), then removing the ones I didn't want (WhatHappened.Nothing).
CheckValues.ForEach(x => returnValue.Add(x()));
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
好的,有一些建议:
del
。 在本例中,我将使用Func
- 但如果您确实想要声明自己的委托类型,请为其指定一个更具描述性的名称,并遵守 . NET 命名约定。您可以使用以下方法,而不是使用匿名方法添加到
CheckValues
:编译器会将方法组转换为委托。
我建议不要使用 Pascal 大小写作为局部变量名称的开头。
returnValues
的集合初始值设定项实际上并没有为您做任何事情 - 只需像平常一样调用List
构造函数,或者使用下面的我的代码,该代码不需要局部变量开始。否则,您确实可以按照 Jared 的建议使用 LINQ,但我的做法略有不同:
编辑:按照建议,这是完整的示例。 不过,它与 Denis 的不太一样......我做了一些更改:)
(我假设
method1
和method2
已被重命名以适应命名约定。当然,在现实生活中我相信他们会有更有用的名字......)Okay, a few suggestions:
del
. In this case, I'd useFunc<WhatHappened>
- but if you do want to declare your own delegate type, give it a more descriptive name, and obey the .NET naming conventions.Instead of using anonymous methods to add to
CheckValues
, you can just use:The compiler will convert the method groups into delegates.
I'd recommend not using Pascal case for a local variable name to start with.
returnValues
isn't really doing anything for you - just call theList<T>
constructor as normal, or use my code below which doesn't require a local variable to start with.Otherwise you can indeed use LINQ as Jared suggests, but I'd do it slightly differently:
EDIT: As suggested, here's the full example. It's not quite the same as Denis's though... I've made a couple of changes :)
(I'm assuming that
method1
andmethod2
have been renamed to fit the naming convention. Of course in real life I'm sure they'd have more useful names anyway...)我会简单地使用 Linq,但这只是我的想法:
请注意,如果您愿意,您也可以使用 Func 而不是声明委托类型,但在这种情况下就不太简洁了。
另外,我会返回一个
IEnumerable
而不是列表,但这完全取决于上下文。I would simply use Linq, but that's just me:
Note that you can also use Func instead of declaring a Delegate type if you want, but that's less terse in that case.
Also, I'd return an
IEnumerable<WhatHappened>
instead of a List, but it's all about the context.您可以通过链接 Select(映射)和Where(过滤器)而不是多个 FOR 循环和 IF 语句来一直使用 lambda
基本上,您应该考虑更多 声明式 而不是 当使用 lambda 时,必须如此。 它将帮助您编写更优雅的代码。
You can go lambda all the way by chaining Select (map) and Where (filter) instead of multiple FOR loops and IF statements
Basically, you should think more declaratively instead of imperatively when work ing with lambdas. It'll help you write more elegant code.
编写以下内容而不是使用 delegate 关键字更为惯用。 但它不会改变底层功能。
另外,我发现将 ForEach 重写为以下内容更具可读性
It's a bit more idiomatic to write the following instead of using the delegate keyword. It doesn't change the underlying functionality though.
Also, I find it more readable to rewrite the ForEach as the following
在我看来,基于这个例子,它看起来不错。 您可以通过替换: 来进行更多重构
:
In my opinion, based on the example, it looks fine. You could refactor even more by replacing:
with:
下面是一个不依赖 LINQ 的解决方案:
警告
这不是性能最佳的解决方案,因为它会迭代两次。
Here's a LINQ-free solution:
caveat
This is not the most performant solution, as it would iterate twice.
我无法理解代码的目的..但是这里是。
使用委托链
更新:并从 Jon n Jared 的帖子中获得了一些可枚举的优点
I can't fathom the purpose of the code.. however here goes.
Used delegate chaining
Update: and picked up some Enumerable goodness from Jon n Jared's posts