从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;
}
问候。
答案 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>
}
}