I'm new to C# and my question is:
I have a class named
AbstractItem
and there are 3 children to this class.
My code is:
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()
});
}
}
}
}
What I'm trying to do is getting all of the values inside this List that matches getByChosenField.
Now, GetByChosenField in my case is a BookName that returns all of the books in the list that are currently with the BookName name.
The code that does the searching is indeed working.
The problem is, if I have a book name Harry Potter inside Cooking and also Reading and\or Science, I get an error:
Additional information: Unable to cast object of type 'CommonBookLib.Cooking' to type 'CommonBookLib.Reading'.
This error occures only when I have at least 2 book names of other Categories (Reading\Cooking\Science\Journal).
In case of one book name, everything is fine.
What am I missing here?
You're nearly there.
You know how to filter the list to those items of a specific subtype.
Just apply that filter to the IEnumerable
you are iterating over
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()
});
}
}
Of course, once we do this, the if
clause becomes superfluous. If there are no items of the matching type, it will simply skip over the loop.
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
}