我们说我有这个课程
public class Person
{
public int PhoneNumber { get; set; }
public string Name { get; set; }
}
我想编写一个方法,可以根据Person和比较字段的属性返回用户列表。
private List<Person> GetResult(Func<Person, object> p, string v)
{
List<Person> data = GetResultsFromDb();
return data.Where(p == v);
}
例如,如果我想得到所有被称为迈克的人,我可以说
var result = GetResult(a => a.Name, "Mike");
或者,如果我想根据电话号码得到结果,我可以说
var result = GetResult(a => a.PhoneNumber, 123);
但是我得到了
Operator == cannot be applied to operands of type 'Expression<Func<Person, object>>' and string
答案 0 :(得分:3)
p
的论点是代表。此类型与string
不能很好地比较(因此您的错误消息)。您需要调用委托来获取值。但是,返回类型的对象不是比较的最佳选择。所以你应该让你的方法通用。既然您是通用的,则不能使用等于运算符==
,但可以使用Equals
。最后,您需要调用ToList
以匹配方法的返回类型:
private List<Person> GetResult<T>(Func<Person, T> p, T v)
{
List<Person> data = GetResultsFromDb();
return data.Where(item => p(item).Equals(v)).ToList();
}
由于参数v
的类型为T
,因此在调用方法时可以推断出T
。这意味着您可以省略类型参数,因此您可以使用GetResult(a => a.Name, "Mike")
代替GetResult<string>(a => a.Name, "Mike")
。
由于在Equals
上定义Equals
,因此在调用Object
时,某些.NET专业人员可能会抱怨您不需要该方法是通用的。您还可以指出,null
值的比较不起作用,IEquatable
实现没有给出任何特殊考虑。如果您想避开所有这些投诉,可以使用EqualityComparer
进行比较:
private List<Person> GetResult<T>(Func<Person, T> p, T v)
{
List<Person> data = GetResultsFromDb();
return data.Where(item => EqualityComparer<T>.Default.Equals(p(item), v)).ToList();
}
答案 1 :(得分:-2)
见下面的代码。你将p用于两个不同的目的
public class Person
{
public int PhoneNumber { get; set; }
public string Name { get; set; }
private List<Person> GetResult(Func<Person, object> p, string v)
{
List<Person> data = GetResultsFromDb();
return data.Where(x => x.Name == v).ToList();
}
private List<Person> GetResultsFromDb()
{
return new List<Person>() {
new Person() { Name = "Mike"},
new Person() { Name = "John"},
new Person() { Name = "Mike"}
};
}
}