我正在尝试采用一种方法并使其成为通用的,我有点卡住,因为该方法使用Linq来查看元素。这是示例方法:
private List<int> GetListFromIDS(string ids, IEnumerable<SubSpace_Function> data)
{
if (string.IsNullOrEmpty(ids))
return null;
var list = ids
.Split(new char[] { ',' })
.Where(x => !string.IsNullOrWhiteSpace(x))
.Select(x => int.Parse(x.Trim()));
return data
.Where(x => list.Contains(x.Function_Id)))
.Select(x => x.Function_Id)
.ToList();
}
更改的部分是类型(SubSpace_Function
)和要查找的属性Function_ID
。
我知道我可以在通用方法签名中将SubSpace_Function
部分更改为T
,但由于每种类型都有自己的属性来查找,我不知道如何'传递'像Function_Id
。
答案 0 :(得分:1)
使用Func
非常容易:
private List<int> GetListFromIDS<T>(string ids, IEnumerable<T> data, Func<T, IEnumerable<int>, bool> filterExpression, Func<T, int> selectExpression)
{
if (string.IsNullOrEmpty(ids))
return null;
var list = ids
.Split(',') // simplify
.Where(x => !string.IsNullOrWhiteSpace(x))
.Select(x => int.Parse(x.Trim()));
return data
.Where(x => filterExpression(x, list))
.Select(selectExpression)
.ToList();
}
并致电:
var data = GetListFromIDS<SubSpace_Function>(
"123,123,123",
someList,
(x, list) => list.Contains(x.Function_Id),
x => x.Function_Id);
另一种方法是调用select Func
inline:
private List<int> GetListFromIDS<T>(string ids, IEnumerable<T> data, Func<T, int> selectExpression)
{
if (string.IsNullOrEmpty(ids))
return null;
var list = ids
.Split(',') // simplify
.Where(x => !string.IsNullOrWhiteSpace(x))
.Select(x => int.Parse(x.Trim()));
return data
.Where(x => list.Contains(selectExpression(x)))
.Select(selectExpression)
.ToList();
}
并致电:
var data = GetListFromIDS<SubSpace_Function>(
"123,123,123",
someList,
x => x.Function_Id);
答案 1 :(得分:0)
我知道这专注于泛型,但我采用了使用界面的方法:
interface ISubSpaceFunction
{
int FunctionId { get; }
}
class Foo : ISubSpaceFunction
{
public int FunctionId => FooMethodForFunctionId();
private int FooMethodForFunctionId()
{
//do foo function id stuff
throw new NotImplementedException();//so it compiles
}
}
class Bar : ISubSpaceFunction
{
public int FunctionId => BarMethodForFunctionId();
private int BarMethodForFunctionId()
{
//do bar function id stuff
throw new NotImplementedException();//so it compiles
}
}
static class MyClass
{
private static List<int> GetListFromIds(string idsString, IEnumerable<ISubSpaceFunction> subSpaceFunctions)
{
var ids = string.IsNullOrWhiteSpace(idsString) ?
Enumerable.Empty<int>() :
idsString.Split(new[] { ',' })
.Where(x => !string.IsNullOrWhiteSpace(x))
.Select(x => x.Trim())
.Select(int.Parse);
var idSet = new HashSet<int>(ids);
return subSpaceFunctions.Select(ssf => ssf.FunctionId)
.Where(ids.Contains)
.ToList();
}
}
class Example
{
public void Test()
{
string ids = "1, 2, 3, 4, 5";
var subSpaceFunctions = new ISubSpaceFunction[] { new Foo(), new Bar() };
var results = MyClass.GetListFromIds(ids, subSpaceFunctions);
}
}
我对这个和相关问题的态度是,获取每个特定类型的Property值的代码必须某处,所以它也可以进入Type类。这确保了如果在其他地方需要Property的值,则不会重复。这也允许混合满足ISubSpaceFunction的多种类型,如示例中所做的那样,并且您可以轻松地让接口指定一些常用方法在其他地方使用。
在编写这些基于LINQ的转换方法时,我也更喜欢在null上返回空集合,以便最小化空值检查&#34;在管道中,&#34;但是快速失败&#34;用例可能会调用null返回值。