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?

+3


source to share


4 answers


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); 

      

+3


source


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();

      



+1


source


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);
}

      

+1


source


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();
            }

      

-1


source







All Articles