как я рассматриваю пустые списки как пустые списки в linq?

Ниже некоторый linqpad тестовый код. Когда это выполняет его ошибки, потому что второй экземпляр "объекта" имеет пустой список подэлементов в противоположность пустому списку.

Я хочу рассматривать обе ситуации (пустой или пустой список) точно таким же образом, но я задался вопросом, был ли более чистый путь, чем просто помещение пустого указателя проверяет список и инициализацию пустого списка, когда существует пустой указатель.

другими словами, я мог сделать это:

from si in (i.subitems == null ? new List<item>() : i.subitems)

но это немного ужасно, и я задался вопросом, как я мог изменить к лучшему это?

public class item
{
    public string itemname { get; set; }
    public List<item> subitems { get; set; }
}

void Main()
{
    List<item> myItemList = new List<item>() 
    {
        new item 
        {
            itemname = "item1",
            subitems = new List<item>()
            {
                new item { itemname = "subitem1" },
                new item { itemname = "subitem2" }
            }
        },
        new item 
        {
            itemname = "item2"
        }
    };

    myItemList.Dump();

    var res = (from i in myItemList
            from si in i.subitems
            select new {i.itemname, subitemname = si.itemname}).ToList();

    res.Dump();
}

в качестве награды вопрос, этот тот же linq может запросить быть представленным как лямбда, и обработка аннулирует тот же путь?

С наилучшими пожеланиями, Chris

7
задан jason 4 February 2010 в 19:02
поделиться

4 ответа

Вы можете использовать оператор объединения с нулевым значением

var res = (from i in myItemList
           from si in i.subitems ?? new List<item>()
           select new { i.itemname, subitemname = si.itemname }).ToList();

Но я думаю, вам следует просто Отфильтруйте пустые

var res = (from i in myItemList
           where i.subitems != null
           from si in i.subitems
           select new { i.itemname, subitemname = si.itemname }).ToList();

Что касается лямбда-версии, вы могли бы сказать

var res = myItemList.Where(x => x.subitems != null)
                    .SelectMany(
                        x => x.subitems.Select(
                            y => new { x.itemname, subitemname = y.itemname }
                        )
                     );

Но версия синтаксиса запроса гораздо более читабельна.

14
ответ дан 6 December 2019 в 05:38
поделиться

Вы можете добавить (злой) метод расширения, который сделает всю работу за вас

public static IEnumerable<T> EnsureNotEmpty<T>(this IEnumerable<T> enumerable) {
  if ( enumerable == null ) {
    return Enumerable.Empty<T>();
  } else { 
    return enumerable;
  }
}
9
ответ дан 6 December 2019 в 05:38
поделиться
from si in (i.subitems ?? new List<item>())

как насчет этого?

11
ответ дан 6 December 2019 в 05:38
поделиться

Необходимо ограничить частоту кадров до X кадров в секунду (чаще всего используется 60 FPS). Это обычная функция в большинстве мультимедийных рамок, включая SFML. Для SFML следует обратиться к методу Window/RenderWindow SetFramerateLimit (неподписанный предел int) .

-121--4541810-

Для обработки выходных данных необходим другой форматер. Поместите его после кода:

NSDateFormatter *anotherDateFormatter = [[NSDateFormatter alloc] init];   
[anotherDateFormatter setDateStyle:NSDateFormatterLongStyle];
[anotherDateFormatter setTimeStyle:NSDateFormatterShortStyle];
NSLog(@"%@", [anotherDateFormatter stringFromDate:myDate]);
-121--1098836-

Дополнительным методом будет запрет пустых подэлементов. Конструктор предмета можно сделать таким образом, чтобы он по умолчанию устанавливал пустой список, а затем не допускал значение NULL в установщике подэлемента.

Это, конечно, предполагает, что у вас есть доступ для изменения предмета.

Нулевой оператор объединения - это то, что вы ищете, как указал Хантер Дэйли

0
ответ дан 6 December 2019 в 05:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: