4

我正在使用一个 linq 查询,它看起来(经过一些简化)类似于以下内容:

List<UserExams> listUserExams = GetUserExams();

var examData = 
from userExam in listUserExams
group by userExam.ExamID into groupExams
select new ExamData()
{
    ExamID = groupExams.Key,
    AverageGrade = groupExams.Average(e => e.Grade),
    PassedUsersNum = groupExams.Count(e => /* Some long and complicated calculation */),
    CompletionRate = 100 * groupExams.Count(e => /* The same long and complicated calculation */) / TotalUsersNum
};

困扰我的是出现两次的计算表达式,用于 PassedUsersNum 和 CompletionRate。

假设,CompletionRate = (PassedUsersNum / TotalUsersNum) * 100我如何通过重用 PassedUsersNum 的计算来编写它,而不是再次编写该表达式?

4

2 回答 2

6

最简单的方法是先使用let注入另一个选择步骤:

List<UserExams> listUserExams = GetUserExams();

var examData = 
    from userExam in listUserExams
    group by userExam.ExamID into groupExams
    let passCount = groupExams.Count( /* long expression */)
    select new ExamData()
    {
        ExamID = groupExams.Key,
        AverageGrade = groupExams.Average(e => e.Grade),
        PassedUsersNum = passCount,
        CompletionRate = 100 * passCount / TotalUsersNum
    };

当然,每个组只会对表达式进行一次评估。

于 2011-06-13T14:41:13.643 回答
1

您也可以将您的 Count func 提取到另一个返回 Func 的方法(如果需要),或者提取双精度并返回 bool 的方法。

List<UserExams> listUserExams = GetUserExams();

var examData = 
from userExam in listUserExams
group by userExam.ExamID into groupExams
select new ExamData()
{
    ExamID = groupExams.Key,
    AverageGrade = groupExams.Average(funcMethod()),
    PassedUsersNum = groupExams.Count(e => traditionalMethod(e)),
    CompletionRate = 100 * groupExams.Count(e => /* The same long and complicated calculation */) / TotalUsersNum
};

// later...
private Func<double,bool> funcMethod(){ return e=> /* your calculation */ }

private bool traditionalMethod(double d){ return /* your calculation */ }
于 2011-06-13T14:46:29.117 回答