在lambda表达式中根据之前设置的另一个值设置一个值?

时间:2016-05-16 17:32:35

标签: c# lambda

我正在为加拿大石油营地开发一个紧急监控工具,因此以下示例极为简化。但是,我认为可以解决这个问题。

我的目标是避免代码重复并清理我的lambda类型转换。

例如而不是:

var dto = results.Select(x => new DTO()
                {
                    Unoccupied = !(x.RoomStatusType == "Checked In" || x.RoomStatusType == "No Sleep"),
                    SwipeTime = x.RoomStatusType == "Checked In" || x.RoomStatusType == "No Sleep" ? x.SwipeTime : null,
                    Mustered = (x.RoomStatusType == "Checked In" || x.RoomStatusType == "No Sleep") && x.SwipeTime != null
                }).ToList();

我想这样做:

var dto = results.Select(x => new DTO()
                {
                    Unoccupied = !(x.RoomStatusType == "Checked In" || x.RoomStatusType == "No Sleep"),
                    SwipeTime = Unoccupied ? null : x.SwipeTime,
                    Mustered = !Unoccupied && SwipeTime != null
                }).ToList();

然而,在后一种实现中,我得到错误说明

  

名称{{'Unoccupied'或'SwypeTime'分别}}不存在   在当前的背景下。

我发现这令人困惑,因为两者似乎都存在于lambda表达式的上下文中。用“this.Unoccupied”或“dto.Unoccupied”之类的东西加上前缀当然没有用。这真让我感到沮丧!

2 个答案:

答案 0 :(得分:4)

一种方法是使用局部变量:

var dto = results.Select(x =>
    {
        var unoccupied = !(x.RoomStatusType == "Checked In" || x.RoomStatusType == "No Sleep");
        var swipeTime = unoccupied ? null : x.SwipeTime;
        return new DTO()
            {
                Unoccupied = unoccupied,
                SwipeTime = swipeTime,
                Mustered = !unoccupied && swipeTime != null
            };
     }).ToList();

答案 1 :(得分:1)

定义Unoccupied,SwipeTime和Mustered的行不是单独的语句。它们是单个对象初始化语句的一部分。这些作业右侧的值必须已经在范围内。

您可以将每个属性的单独赋值语句重写为多行Lambda表达式,例如:

var dtoList = results.Select(x => {
    var dto = new DTO();
    dto.Unoccupied = !(x.RoomStatusType == "Checked In" || x.RoomStatusType == "No Sleep");
    dto.SwipeTime = dto.Unoccupied ? null : x.SwipeTime;
    dto.Mustered = !dto.Unoccupied && dto.SwipeTime != null;
    return dto;
}).ToList();