C# foreach 在摘要的 children 上

C# foreach on children of an abstract

我是 C# 新手,我的问题是:
我有一个名为

的 class

AbstractItem

这个class有3个children。 我的代码是:

private void AddChecker(List<AbstractItem> getByChosenField)
    {
        if (getByChosenField == null)
        {
            MessageBox.Show("Entry list is currently empty.");
        }
        else {
            LibraryList.Items.Clear(); // simply if there are no results then list remains empty.
            if (getByChosenField.OfType<Reading>().Count() > 0)
            {
                foreach (Reading item in getByChosenField)
                {
                    LibraryList.Items.Add(
                        new MyItems
                        {
                            ItemName = item.ItemName,
                            CopyNumber = int.Parse(item.CopyNumber.ToString()),
                            Guid = int.Parse(item.Guid.ToString()),
                            TimePrinted = item.Time,
                            BestSeller = item.BestSeller,
                            Category = item.BookCategory.ToString(),
                            SubCategory = item.ReadingBookSubCategory.ToString()
                        });
                }
            }
            if (getByChosenField.OfType<Cooking>().Count() > 0)
            {
                foreach (Cooking item in getByChosenField)
                {
                    LibraryList.Items.Add(
                        new MyItems
                        {
                            ItemName = item.ItemName,
                            CopyNumber = int.Parse(item.CopyNumber.ToString()),
                            Guid = int.Parse(item.Guid.ToString()),
                            TimePrinted = item.Time,
                            BestSeller = item.BestSeller,
                            Category = item.BookCategory.ToString(),
                            SubCategory = item.CookingBookSubCategory.ToString()
                        });
                }
            }
            if (getByChosenField.OfType<Science>().Count() > 0)
            {
                foreach (Science item in getByChosenField)
                {
                    LibraryList.Items.Add(
                        new MyItems
                        {
                            ItemName = item.ItemName,
                            CopyNumber = int.Parse(item.CopyNumber.ToString()),
                            Guid = int.Parse(item.Guid.ToString()),
                            TimePrinted = item.Time,
                            BestSeller = item.BestSeller,
                            Category = item.BookCategory.ToString(),
                            SubCategory = item.ScienceBookSubCategory.ToString()
                        });
                }
            }
            if (getByChosenField.OfType<Journal>().Count() > 0)
            {
                foreach (Journal item in getByChosenField)
                {
                    LibraryList.Items.Add(
                        new MyItems
                        {
                            ItemName = item.ItemName,
                            CopyNumber = int.Parse(item.CopyNumber.ToString()),
                            Guid = int.Parse(item.Guid.ToString()),
                            TimePrinted = item.Time,
                            Category = "Journal",
                            SubCategory = item.JournalCategory.ToString()
                        });
                }
            }
        }
    }

我想要做的是获取此列表中与 getByChosenField 匹配的所有值。
现在,在我的例子中,GetByChosenField 是一个 BookName,returns 列表中当前具有 BookName 名称的所有书籍。
执行搜索的代码确实有效。
问题是,如果我在 CookingReading [=42] 里面有书名 Harry Potter =] 科学,我得到一个错误:

Additional information: Unable to cast object of type 'CommonBookLib.Cooking' to type 'CommonBookLib.Reading'.

只有当我有至少 2 个其他类别的书名 (Reading\Cooking\Science\Journal) 时才会出现此错误。
如果一个书名,一切都很好。
我在这里错过了什么?

你快到了。

您知道如何将列表过滤为特定子类型的项目。

只需将该过滤器应用于您正在迭代的IEnumerable

        if (getByChosenField.OfType<Reading>().Any()) // Faster than Count() > 0
        {
            foreach (Reading item in getByChosenField.OfType<Reading>())
            {
                LibraryList.Items.Add(
                    new MyItems
                    {
                        ItemName = item.ItemName,
                        CopyNumber = int.Parse(item.CopyNumber.ToString()),
                        Guid = int.Parse(item.Guid.ToString()),
                        TimePrinted = item.Time,
                        BestSeller = item.BestSeller,
                        Category = item.BookCategory.ToString(),
                        SubCategory = item.ReadingBookSubCategory.ToString()
                    });
            }
        }

当然,一旦我们这样做了,if 子句就变得多余了。如果没有匹配类型的项目,它将直接跳过循环。

 foreach (Reading item in getByChosenField.OfType<Reading>())
 {
      // Add the Reading item
 }
 foreach(Cooking item in getByChosenField.OfType<Cooking>()) 
 {
    //Add the Cooking item
 }
 foreach(Science item in getByChosenField.OfType<Science>())
 {
    // Add the science item
 }