C# 传递 Func> 数组到一个方法
我的第一篇(也是非常可怕的帖子)如下。
我尝试做一个完整的例子,我想要得到什么。我希望这能得到更好的解释。
using System;
using System.Collections.Generic;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
List<Boy> boys = new List<Boy>();
boys.Add(new Boy("Jhon", 7));
boys.Add(new Boy("Oscar", 6));
boys.Add(new Boy("Oscar", 7));
boys.Add(new Boy("Peter", 5));
ClassRoom myClass = new ClassRoom(boys);
Console.WriteLine(myClass.ByName("Oscar").Count); // Prints 2
Console.WriteLine(myClass.ByYearsOld(7).Count); // Prints 2
// This has errors...................
// But this is as I would like to call my BySomeConditions method....
Console.WriteLine( // It should print 1
myClass.BySomeConditions([myClass.ByName("Oscar"),
myClass.ByYearsOld(7)]
)
);
Console.ReadKey();
}
class ClassRoom
{
private List<Boy> students;
public ClassRoom(List<Boy> students)
{
this.students = students;
}
public List<Boy> ByName(string name)
{
return students.FindAll(x => x.Name == name);
}
public List<Boy> ByYearsOld(int yearsOld)
{
return students.FindAll(x => x.YearsOld == yearsOld);
}
// This has ERRORS.......................
public List<Boy> BySomeConditions(params Func<X, List<Boy>>[] conditions)
{
IEnumerable<Boy> result = students;
foreach (var condition in conditions) {
// I want it ONLY be called with existent functions (ByName and/or ByYearsOld)
result = result.Intersect(condition(this));
}
}
}
class Boy
{
public string Name { get; set; }
public int YearsOld { get; set; }
public Boy(string name, int yearsOld)
{
Name = name;
YearsOld = yearsOld;
}
}
}
}
==============第一篇文章===================== 您好,
我有一个带有方法的类:
public class X
{
private readonly List<string> myList;
public X(List<string> paramList) // string is really an object
{
myList = paramList;
}
// Now I want this...
public List<string> CheckConditions(params Func<T, List<string>>[] conditions)
{
var result = myList;
foreach (Func<T, List<string>> condition in conditions)
{
result = result.Intersect(condition(T));
}
}
public List<string> check1(string S)
{
return myList.FindAll(x => x.FieldS == S);
}
public List<string> check1(int I)
{
return myList.FindAll(x => x.FieldI == I);
}
}
抱歉,如果有一些错误,我是从头开始编写的,以避免复杂的实际情况。
我想要的是像这样调用我的方法:
X.check1("Jhon");
or
X.check2(12);
or (这是我问题的目标):
X.CheckConditions(X.check1("Jhon"), X.chek2(12));
感谢并抱歉我的糟糕例子......
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您可以将函数重写为如下所示:
您的调用将是
X.CheckConditions(()=>X.check1("Jhon"), ()=>X.chek2(12));< /code>
并且您需要为 x 提供一个实例(因为这些方法是实例方法而不是静态方法)
在您的示例中,您将 T 作为参数传递给函子,但 T 是类型参数,因此不能将其传递为该方法的参数。你的意思是传递一个值吗?
这就要求您澄清为什么要这样做。也许如果您提供有关您想要完成的任务(而不是如何完成)的详细信息,那么您可以获得更好的问题解决方案。
you could rewrite you function to look like this:
your call would then be
X.CheckConditions(()=>X.check1("Jhon"), ()=>X.chek2(12));
and you need to provide an instance for x (since the methods are instance methods and not static methods)
In your example you pass T as an argument to the functor but T is a type argument som it can't be passed as an argument to the method. Did you mean to pass a value?
This begs for a clarification of why you would want to do this. Maybe if you provided details on what you are trying to accomplish (as opposed to how) then you could get a better solution to your problem.
您传递给您的
不是对函数的引用,而是它们调用的返回值。
现在,如果您传递函数引用 - 它不带有参数,除非您构造并传递一个将包含函数引用及其应处理的参数的数据结构。
在这种情况下 - 泛型不是解决方案。您应该考虑遵循另一种模式,例如命令模式或策略模式,在其中传递给检查器对象的
CheckConstruction
实例,每个实例都使用它应该使用的参数进行实例化,并且要么实现要么是由验证函数提供。What you pass to your
is not a reference to the functions, but the returned value of their invocation.
Now, if you pass function reference - it does not come with parameters, unless you construct and pass a data-structure that will contain the function reference and the arguments it should work on.
In this case - generics is not the solution. You should consider another pattern to follow, like command pattern or strategy pattern, where you pass to your
CheckConstruction
instances of checker-objects, each is instantiated with the parameters it should work on, and either implements or is provided by the validation function.目前还不清楚你的 T 来自哪里。
这满足您的要求吗?
然后后来:
It is unclear where your T comes from.
Does this meet your requirements?
Then later:
您需要更改
CheckConditions
的方法签名,它接受可变数量的List
,而不是函数。check1
的返回类型是List
,因此它需要是CheckConditions
接受的参数类型。You need to change the method signature of
CheckConditions
, it's accepting a variable number ofList<string>
, not functions.The return type of
check1
isList<string>
, so that needs to be the type of the parameter thatCheckConditions
accepts.没有理由使其通用,您知道您想要对
X
的当前实例进行操作(因此传入this
,而不是T 类型参数)。您需要清理一些东西才能编译(返回
result
并使result
的类型与Intersect
调用兼容)。您可以这样定义它:Ant 然后这样调用它:
话虽如此,我不确定为什么您不只是传递这些函数的结果,而不是传递实际的函数:
然后像这样调用它您的示例,而不是传入 lambda 表达式。
There's no reason to make it generic, you know that you want to operate on the current instance of
X
(so pass inthis
, instead of theT
type parameter). You need to cleanup a few things to to get it to compile (returnresult
and make the type ofresult
and theIntersect
call compatible). You can define it like this:Ant then call it like this:
All that said, I'm not sure why you wouldn't just pass around the results of these functions, instead of passing the actual functions around:
Then call it as in your example, rather than passing in lambda expressions.