我有一个简单的对象列表,我想应用不同的过滤器和顺序选择器。对于筛选器来说是可以的,但是对于顺序来说,我不知道如何定义一个 "通用 "选择器。
// The selector is always a bool
Func<MyNode, bool> isChild = x => x.Age < 18;
Func<MyNode, bool> isAdult = x => x.Age >= 18;
// So it's always ok to use
Func<MyNode, bool> isAgeOk = isAdult;
// The sort field can be different type (int, string, ...)
Func<MyNode, string> sortByName = x => x.Name;
Func<MyNode, int> sortByAge = x => x.Age;
Func<MyNode, int> sortById = x => x.Id;
// --------------> Is there a way to use a kind of generic declaration Func<MyNode, T> ?
Func<MyNode, int> currentSort = sortByAge;
// With this declaration, i can't use : Func<MyNode, int> currentSort = sortByName
List<MyNode> LstNodes = new List<MyNode>();
// ...Stuff to get nodes
// If I have this kind of linq, it's ok, but current sort is Fixed (Func<MyNode, int> in this example)
var result = LstNodes.Where(isAgeOk).Distinct().OrderBy(currentSort).ToList();
简单的类定义是
public class MyNode
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
我知道进一步声明失败的原因是编译器错误CS1662 "不能将匿名方法块转换为委托类型'委托类型',因为块中的一些返回类型不能隐式转换为委托返回类型",但是否可以定义一种类似于.NET的通用声明?
Func<MyNode, T> currentSort = sortByAge; // <-- Fails Compiler error CS1662
还是有其他的方法来处理?
正如HimBromBeere所评论的,最好的方法是使用IComparable类型。
代码。
Func<PersonTest, IComparable> sortByName = x => x.Name;
Func<PersonTest, IComparable> sortByAge = x => x.Age;
Func<PersonTest, IComparable> sortByLastName = x => x.LastName;
// --------------> Is there a way to use a kind of generic declaration Func<MyNode, T> ?
Func<PersonTest, IComparable> currentSort = sortByName;
你的所有类型都实现了 IComparable
. 作为 Func
是反变量,你可以分配任何返回该接口实例的委托。
所以这就可以了。
Func<MyNode, IComparable> myDelegate = myFunctionReturningString;
Func<MyNode, IComparable> myDelegate = myFunctionReturningInt;
Func<MyNode, IComparable> myDelegate = myFunctionReturningBool;
我只想用lambdas
var list = new List<MyNode>() {
new MyNode(){Id = 1, Name = "name1", Age = 1},
new MyNode(){Id = 2, Name = "name2", Age = 2},
new MyNode(){Id = 3, Name = "name3", Age = 3},
new MyNode(){Id = 4, Name = "name4", Age = 4},
new MyNode(){Id = 5, Name = "name5", Age = 5},
new MyNode(){Id = 6, Name = "name6", Age = 6},
new MyNode(){Id = 7, Name = "name7", Age = 7},
new MyNode(){Id = 8, Name = "name8", Age = 8},
};
var result = list.Where(n => n.Age >= 3).OrderBy(n => n.Age).ToList();
你可以用 IComparable
.
https:/dotnetfiddle.net23R97J。
Func<MyNode, IComparable> sortByName = x => x.Name;
Func<MyNode, IComparable> sortByAge = x => x.Age;
Func<MyNode, IComparable> sortById = x => x.Id;
var currentSort = sortByAge;
EDIT: 就像其他人已经提到的那样,最好使用 IComparable
而不是 object
,我之前的建议。