Проблема с наследованием и Списком <>

У меня есть названная Группировка абстрактного класса. У меня есть подкласс под названием GroupingNNA.

public class GroupingNNA : Grouping {
  // blah blah blah
}

У меня есть Список, который содержит объекты типа GroupingNNA, но, как на самом деле объявляют, содержит объекты Группировки типа.

List<Grouping> lstGroupings = new List<Grouping>();
lstGroupings.Add(
  new GroupingNNA { fName = "Joe" });
lstGroupings.Add(
  new GroupingNNA { fName = "Jane" });

Проблема: продолжающие LINQ запрашивают удары на мне из-за того, что lstGroupings объявляется как Список <Группировка>, и fName является свойством GroupingNNA, Не Группируясь.

var results = from g in lstGroupings
              where r.fName == "Jane"
              select r;

О, и это - ошибка компилятора, не ошибка периода выполнения. Заранее спасибо за любую справку на этом!

Подробнее: Вот фактический метод, который не скомпилирует. OfType () зафиксировал запрос LINQ, но компилятору не нравится то, что я пытаюсь возвратить анонимный тип как Список <Группировка>.

private List<Grouping> ApplyFilterSens(List<Grouping> lstGroupings, string fSens) {

  // This works now! Thanks @Lasse
  var filtered = from r in lstGroupings.OfType<GroupingNNA>()
                 where r.QASensitivity == fSens
                 select r;

  if (filtered != null) {
    **// Compiler doesn't like this now**
    return filtered.ToList<Grouping>();
  }
  else
    return new List<Grouping>();
  }
7
задан Jagd 13 May 2010 в 22:41
поделиться

2 ответа

Попробуйте:

= from g in lstGroupings.OfType<GroupingNNA>()

это пропустит любые элементы не типа GroupingNNA , а также заставит компилятор использовать GroupingNNA как тип для g .

В ответ на комментарий и отредактированный вопрос. Нет, компилятор определенно не обрадуется вашей измененной коллекции, но вы можете это исправить:

return new List<Grouping>(filtered.ToArray());

Это основано на том факте, что массивы в .NET совпадают / противовариантны, что позволяет компилятору обрабатывать GroupingNNA [] как Группировка [] для конструктора.

Кроме того, вам не нужна проверка if (filter! = Null) , вы получите коллекцию в отфильтрованной , она может просто не создавать никаких элементов, но отфильтровано всегда будет отличным от null .

Это означает, что ваш код может быть записан как:

var filtered = from r in lstGroupings.OfType<GroupingNNA>()
               where r.QASensitivity == fSens
               select r;
return new List<Grouping>(filtered.ToArray());

или даже просто:

return new List<Grouping>((from r in lstGroupings.OfType<GroupingNNA>()
                           where r.QASensitivity == fSens
                           select r).ToArray());

или даже короче, если вы отбросите синтаксис linq:

return new List<Grouping>((lstGroupings.OfType<GroupingNNA>()
    .Where(r => r.QASensitivity == fSens).ToArray());

Обратите внимание, что вы, конечно, можете использовать OfType для пойдите и другим путем:

return filtered.OfType<Grouping>().ToList();

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

6
ответ дан 6 December 2019 в 23:02
поделиться

Вызывая ToList(), вы снова оказываетесь в той же лодке, что и раньше - общая ковариация/контравариация не поддерживается - например, List не совместим с List или не конвертируем в/из List.

Вам необходимо использовать filtered.OfType(). ToList(); - первый возвращает вас к IEnumerable вместо IEnumerable, а затем ToList просто преобразует IEnumerable в List того же общего типа.

5
ответ дан 6 December 2019 в 23:02
поделиться
Другие вопросы по тегам:

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