LINQ查询中的对象初始值设定项 - 是否可以重用计算数据?

时间:2011-06-13 14:39:23

标签: c# linq object-initializers

我正在使用一个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的计算来编写它,而不是再次编写该表达式?

2 个答案:

答案 0 :(得分: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
    };

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

答案 1 :(得分:1)

你也可以将你的Count func提取到另一个方法中,如果你想要的话,它会返回一个Func,或者一个带有double的方法并返回一个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 */ }