[英]Pass property name as parameter
我有以下课程
public class School
{
public List<Student> Students { get; set; }
public List<Teacher> Teachers { get; set; }
}
现在我有了这个方法
public bool Evaluate(??)
{
var school = DbContext.Schools.FirstOrDefault();
return school.??.Any(/*some expresions*/)
}
我应该能够在 ?? 并使用它以便我可以同时使用
return school.Students.Any(/*some expresions*/)
return school.Teachers.Any(/*some expresions*/)
那么如何用学生或教师替换问号?
编辑:
public class Student
{
public string FullName { get; set; }
public bool Registered { get; set; }
public bool Passed { get; set; }
}
public class Teacher
{
public string FullName { get; set; }
public bool CanEvaluate { get; set; }
public bool Validator { get; set; }
}
public class DynamicCheckTest
{
public bool MyExpression<T>(List<T> items, string name,
Expression<Func<T, bool>> expression)
{
return items.Any(x => expression.Compile()(x));
}
}
public static bool Check<T>(this List<T> items, Func<T, bool> compiledExp)
{
return items.Any(x => compiledExp(x));
}
Students.Check(x => x.Name == "Mike" && x.Registered); // example
Teachers.Check(x => x.Name == "Jack" && x.CanEvaluate);// example
现在我要经过学校,里面有学生和老师,但我不知道会提前打电话给哪一个
解决“将属性名称作为参数传递”请求,您可以为此使用反射,但我认为这不是一个好方法。 相反,可以使用Func<School, List<TElement>>
来选择所需的List<>
属性来评估...
public bool Evaluate<TElement>(Func<School, List<TElement>> listSelector)
where TElement : Person
{
School school = DbContext.Schools.FirstOrDefault();
DateTime today = DateTime.Today;
return listSelector(school)
// For example, check if today is the birthday of anyone in the selected list
.Any(person => person.DateOfBirth.Month == today.Month && person.DateOfBirth.Day == today.Day);
}
正如@Enigmativity 指出的那样, 类型约束是必要的,以便将许多有意义的条件传递给Any()
,这也假设/要求Student
和Teacher
具有共同的祖先,像这样......
public abstract class Person
{
public DateTime DateOfBirth
{
get;
}
}
public class Student : Person
{
}
public class Teacher : Person
{
}
然后,您将使用lambda 表达式来指定所需的List<>
...
bool isAnyStudentsBirthday = Evaluate(school => school.Students);
bool isAnyTeachersBirthday = Evaluate(school => school.Teachers);
只要您希望Any()
考虑的成员在约束类型(即Person
)中可用,这就会起作用。 如果您想使用特定于Student
或Teacher
类的成员进行过滤,最好的办法是使用类似@Enigmativity's answer 的方法,其中过滤器本身是一个参数,并接收与所选List<>
存储相同的派生类型。
请注意,如果您想将Evaluate()
与School
一些其他集合属性一起使用,这些属性不是专门为List<>
,或者只是知道Any()
需要的是一个IEnumerable<>
,您可以更改返回类型(最后一个类型将Func<>
参数) 改为限制较少的内容...
Func<School, IList<TElement>>
Func<School, ICollection<TElement>>
Func<School, IEnumerable<TElement>>
你可以使用这个方法:
public bool Evaluate<T>(Func<School, List<T>> project, Func<T, bool> filter)
{
var school = DbContext.Schools.FirstOrDefault();
return project(school).Any(filter);
}
如果我们假设Student
和Teacher
的实现是这样的:
public class Student
{
public string Name;
}
public class Teacher
{
public string Subject;
}
那么你可以这样做:
bool hasFred = Evaluate(school => school.Students, student => student.Name == "Fred Nerk");
bool teachArt = Evaluate(school => school.Teachers, teacher => teacher.Subject == "Art");
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.