List enumeration of class inheriting 2 classes
I used the following code to create a class in my enum code:
public class ItemCollection : IEnumerable<AbstractItem>
{
private List<AbstractItem> Items;
public IEnumerator<AbstractItem> GetEnumerator()
{
return Items.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
This works well, but I ran into a problem: AbstractItem has two inheriting classes: Book and Journal, both inherit objects from AbstractItem and have their own (they both get "Name" from AbstractItem, but only Book has "BGenre", and only Journal has "JTopic"), and because I have implemented the iEnumerator of AbstractItem, I cannot use the objects that inheriting classes have in the foreach loop. How can I fix this?
source to share
You can use Linq to filter Book
s, Journal
whatever:
ItemCollection collection = ...
var books = collection
.OfType<Book>();
var journals = collection
.OfType<Journal>();
for example, to print all BGenre
s:
String bGenres = String.Join(Environment.NewLine, collection
.OfType<Book>()
.Select(book => book.BGenre.ToString()));
Console.Write(bGenres);
source to share
foreach (AbstractItem item in collection)
{
// common book and journal code here
if (item is Book)
{
// some code for books
}
else if (item is Journal)
{
// some code for journals
}
}
// another way:
List<Book> books = collection.OfType<Book>().ToList();
List<Journal> journals = collection.OfType<Journal>().ToList();
source to share
You can use generics:
public class ItemCollection<T> : IEnumerable<T>
{
private List<T> Items;
public IEnumerator<T> GetEnumerator()
{
return Items.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
Then you can do something like:
var books = new ItemCollection<Book>();
foreach(var book in books)
{
doSomething(book.BookProperty);
}
or
var journals = new ItemCollection<Journal>();
foreach(var journal in journals)
{
doSomething(journal.JournalProperty);
}
or when referring to abstract
var items = new ItemCollection<AbstractItem>();
foreach(var item in items)
{
doSomething(item.AbstractItemProperty);
}
source to share
I don't know if you are doing your abstract class well. but in this case you can use reflection to access the properties of the class. eg:
foreach (AsbtractClass Item in ItemCollection)
{
System.Reflection.PropertyInfo BGenre = Item.GetType().GetProperty("BGenre");
System.Reflection.PropertyInfo JTopic = Item.GetType().GetProperty("JTopic");
if (BGenre != null) TxtResultBGenre.Text = BGenre.GetValue(Item).ToString();
if (JTopic != null) TxtResultJTopic.Text = BGenre.GetValue(Item).ToString();
}
Or you can parse the data type of the Item and get a known property.
foreach (AsbtractClass Item in ItemCollection)
{
if (Item is Book)
TxtResultBGenre.Text = System.Reflection.PropertyInfo BGenre = Item.GetType().GetProperty("BGenre").GetValue(Item).ToString();
else if (Item is Journal)
TxtResultJTopic.Text = System.Reflection.PropertyInfo JTopic = Item.GetType().GetProperty("JTopic").GetValue(Item).ToString();
}
source to share