将对象列表转换为元组列表而无需迭代

7

我正在尝试为一组ef对象添加一个额外的参数以跟踪处理过程,但我不断遇到必须显式初始化每个列表项的问题。有没有正确的linq方法来解决这个问题?除了简洁之外,在这种情况下使用linq语法是否有任何优势?

List<app_subjects> subjectList = AppMySQLQueries.GetAllSubjects();
List<Tuple<app_subjects, bool>> subjectCollection = new List<Tuple<app_subjects, bool>>(subjectList.Count);

foreach (app_subjects subject in subjectList)
{
     subjectCollection.Add(Tuple.Create(subject, false));
}

我已经搜索了这个网站,但没有找到相关信息。

LINQ可以做到这一点,但它看起来非常类似于传统的forforeach - King King
2
LINQ 也会执行迭代,(在内部)。 - Habib
@Habib 不同之处在于,使用LINQ可能能够推迟工作的执行。 - Servy
@Servy,没错,但是考虑到示例代码,如果他需要调用list函数,这种情况就不适用了。 - evanmcdonnal
1
@Dantix 在一个成熟的代码库中,你经常无法控制使用哪种类型的集合。 - evanmcdonnal
显示剩余3条评论
4个回答

17

你只需要在这里使用一个投影操作 (Select),它会将 lambda 表达式中的转换应用于源集合中的每个元素。

List<Tuple<app_subjects, bool>> tuples = subjectList.Select(x => new Tuple<app_subjects, bool>(x, false)).ToList();

ToList() 的调用并非完全必要,如果将其删除,则该方法将返回一个 IEnumerable<Tuple<app_subjects, bool>>。如果你只是打算在之后迭代元组集合,那么应该删除 ToList 调用,因为它会强制执行(枚举 IEnumerable),然后你的下一个操作(foreach)也会执行相同的操作,使代码性能更差。


抱歉,lambda表达式“x.subject”无效,因为它解析为ef类中的一个方法,而不是类本身。 - aldosa
1
@AldoSalzberg,是的,我已经进行了编辑。我原以为app_subjectsubjectList集合中对象的属性。但实际上它只是一个List<app_subject>,所以应该用x代替x.subject - evanmcdonnal
使用ConvertAll代替。 - It'sNotALie.
@evan 它更快(只枚举一次) - It'sNotALie.
我得到了这个错误:'只有无参数构造函数和初始化程序在LINQ to Entities中受支持'。 - QMaster
显示剩余5条评论

7
像这样吗?
subjectList.Select(s => Tuple.Create(s, false)).ToList();

2

随着C# 10.0 (.NET 6.0)的到来,这变得更加简单和清晰。除了命名元组外,我们还可以通过将值放在圆括号中来声明一个元组。

List<(string NamedProperty1, int NamedProperty2)> _tuples = new();
_tuples = _objectList.Select(o => (o.SomeProperty1, o.SomeProperty2)).ToList();

0

试试这个。

List<Tuple<app_subjects, bool>> subjectCollection = subjectList.CovertAll( subject => new Tuple<app_subjects, bool>(){
subject,
false
}).ToList();

抱歉,必须使用Tuple.Create(...)而不是new Tuple。 - aldosa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接