使用foreach循环显示对象

时间:2011-11-03 06:05:14

标签: c# object foreach arraylist

从ArrayList检索数据并将其显示到文本框中时遇到问题。我收到错误:Unable to cast object of type 'Lab_9.Book' to type 'Lab_9.Magazine'。我试过使用2个foreach循环,但这似乎是不可能的。我怎么能避免这个问题?

此处出现问题:

    // Displaying all Book objects from pubs ArrayList.
    foreach (Book list in pubs)
    {
        bookNumber++; // Count books from the begining.

        // Displaying and formating the output 
        // in txtBookList textbox.
        bookList.txtBookList.Text +=
            "=== Book " + bookNumber + " ===" + Environment.NewLine +
            list.Title + Environment.NewLine +
            list.getAuthorName() + Environment.NewLine +
            list.PublisherName + Environment.NewLine +
            "$" + list.Price + Environment.NewLine
            + Environment.NewLine;
    }

问候。

3 个答案:

答案 0 :(得分:3)

这将允许你只有一个循环,但它不是很漂亮

foreach (object publication in pubs)
{
   var book = publication as Book;
   var magazine = publication as Magazine;
   if (book != null) {
     //it's a book, do your thing
   } else if (magazine != null) {
     //it's a magazine, do your thing
   } else {
    throw new InvalidOperationException(publication.GetType().Name + " is not a book or magazine: ");
   }
}

您真的想要定义一个封装所有出版物的公共属性和方法的接口,而不是继承。

public interface IPublication
{
  string Title {get;set;}
  float Price {get;set;}
  // etc.
}

接下来让您的类实现接口

public class Book : IPublication
{
  public string Title {get;set;}
  public float Price {get;set;}
  //the rest of the book implementation
}

public class Magazine: IPublication

{
  public string Title {get;set;}
  public float Price {get;set;}
  //the rest of the magazine implementation
}

此时你已经拥有了更多的灵活性,但是为了你的目的,你可以保持其余代码的原样,只使用一个更清晰的循环,更多内容与jwJung的解决方案

foreach (var publication in pubs.OfType<IPublication>())
{
  // publication is either a book or magazine, we don't care we are just interested in the common properties
  Console.WriteLine("{0} costs {1}",  publication.Title, publication.Price);
}

答案 1 :(得分:2)

pub对象(ArrayList)的项目是Book和Magazine类型的Object类型实例。因此,您需要使用.OfType()进行过滤以显示每种类型。此方法将仅返回ArrayList中的目标类型(T)的实例。

foreach (Book list in pubs.OfType<Book>())
{
}

foreach (Magazine list in pubs.OfType<Magazine>())
{
}

要组合两个foreach,我建议您重写ToString()或创建一个具有字符串属性的基类。要使用基类,请将所有值(例如title +“,”+ bookNumber ...)设置为字符串属性。我将告诉你重写ToString()。

internal class Book
{
    public override string ToString()
    {
        return "=== Book " + bookNumber + " ===" + Environment.NewLine +....;
    }
}

internal class Magazine
{
    public override string ToString()
    {
        return "=== Publication: " + bookNumber + ....;
    }
}

然后你可以结合两个循环。

foreach (string item in pub)
{
    Console.WriteLine(item.ToString());
}

答案 2 :(得分:1)

编辑:我已经重新阅读了您的问题和您的评论(抱歉),我想您正在寻找的是:

foreach (var list in pubs)
{
    if(list is Book)
    {
        Book tmp = (Book)list;
        // Print tmp.<values> 
    }

    if(list is Magazine)
    { 
        Magazine tmp = (Magazine)list;
        // Print tmp.<values>         
    }
}