簡體   English   中英

將屬性名稱作為參數傳遞

[英]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() ,這也假設/要求StudentTeacher具有共同的祖先,像這樣......

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 )中可用,這就會起作用。 如果您想使用特定於StudentTeacher類的成員進行過濾,最好的辦法是使用類似@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);
}

如果我們假設StudentTeacher的實現是這樣的:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM