我的第一个(也是非常可怕的帖子)在下面。
我尝试做一个完整的例子,我想得到什么。我希望这会更好地解释一下。
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");
或
X.check2(12);
或(这是我的问题的目标):
X.CheckConditions(X.check1("Jhon"), X.chek2(12));
我的可怜的榜样感谢和抱歉...
答案 0 :(得分:3)
目前还不清楚你的T来自哪里。
这是否符合您的要求?
public class X<T>
{
private List<T> myList;
public List<T> CheckConditions(params Func<T, bool>[] conditions)
{
IEnumerable<T> query = myList;
foreach (Func<T, bool> condition in conditions)
{
query = query.Where(condition);
}
return query.ToList();
}
}
然后:
List<T> result = X.CheckConditions(
z => z.FieldS == "Jhon",
z => z.FieldI == 12
);
答案 1 :(得分:2)
您需要更改CheckConditions
的方法签名,它接受可变数量的List<string>
,而不是函数。
public List<string> CheckConditions(params List<string>[] lists)
check1
的返回类型为List<string>
,因此需要是CheckConditions
接受的参数类型。
答案 2 :(得分:1)
没有理由将其设为通用,您知道您希望对X
的当前实例进行操作(因此传入this
,而不是T
类型参数)。您需要清理一些内容以使其编译(返回result
并使类型result
和Intersect
调用兼容)。您可以这样定义:
public List<string> CheckConditions(params Func<X, List<string>>[] conditions)
{
IEnumerable<string> result = myList;
foreach (var condition in conditions)
{
result = result.Intersect(condition(this));
}
return result.ToList();
}
Ant然后将其称为:
xInstance.CheckConditions(x => x.check1("JHon"), x => x.check1(12));
所有这一切,我不确定为什么你不会只是传递这些函数的结果,而不是传递实际的函数:
public List<string> CheckConditions(params List<string>[] conditions)
{
IEnumerable<string> result = myList;
foreach (var condition in conditions)
{
result = result.Intersect(condition);
}
return result.ToList();
}
然后在你的例子中调用它,而不是传入lambda表达式。
答案 3 :(得分:0)
你传递给你的
X.CheckConditions
不是对函数的引用,而是对它们的调用的返回值。
现在,如果你传递函数引用 - 它没有参数,除非你构造并传递一个数据结构,它将包含函数引用及它应该处理的参数。
在这种情况下 - 泛型不是解决方案。你应该考虑另一种模式,比如命令模式或策略模式,你传递给检查器对象的CheckConstruction
个实例,每个模式都用它应该处理的参数实例化,并且实现或由验证功能。
答案 4 :(得分:0)
你可以改写你的功能看起来像这样:
// 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));
}
}
您的通话将是X.CheckConditions(()=>X.check1("Jhon"), ()=>X.chek2(12));
并且你需要为x提供一个实例(因为这些方法是实例方法,而不是静态方法)
在您的示例中,您将T作为参数传递给仿函数,但T是一个类型参数,因为它不能作为参数传递给方法。你的意思是传递一个值吗?
这需要澄清你为什么要这样做。也许如果您提供了有关您要完成的任务的详细信息(而不是如何),那么您可以更好地解决您的问题。