C# 显示不同对象的数组c(类继承)
我的代码有问题。我是一个新的继承者,到目前为止,我只听过一次关于它的讲座,非常感谢大家的帮助。有人给了我这个问题,我想我已经差不多解决了。创建一个Book类,添加两个子类。全部显示。加上其他东西,但这是核心问题 当我试图在for循环中显示每个对象及其信息时,我不知道如何访问教科书的BookGrade。我做了一系列的书,把所有的东西都放在里面。我知道这不对,但我不知道该怎么办。我试过制作一系列这样的教科书C# 显示不同对象的数组c(类继承),c#,class,object,inheritance,C#,Class,Object,Inheritance,我的代码有问题。我是一个新的继承者,到目前为止,我只听过一次关于它的讲座,非常感谢大家的帮助。有人给了我这个问题,我想我已经差不多解决了。创建一个Book类,添加两个子类。全部显示。加上其他东西,但这是核心问题 当我试图在for循环中显示每个对象及其信息时,我不知道如何访问教科书的BookGrade。我做了一系列的书,把所有的东西都放在里面。我知道这不对,但我不知道该怎么办。我试过制作一系列这样的教科书 TextBook[] bookArray = new TextBook[3] { Book1
TextBook[] bookArray = new TextBook[3] { Book1, TBook1, CBook1};
但接下来我需要向Book1添加一个cast,这很有效,但我仍然不能隐式地将类型“CoffeeTableBook”转换为“教科书”。我明白了,但我不知道如何避开它。我发现此错误“Book”不包含“BookGrade”的定义
我有三节课,书,课本和咖啡桌。教科书和咖啡桌图书课程都是从图书类衍生出来的
提前感谢所有花时间帮助我的人
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BookDemo
{
class Program
{
static void Main(string[] args)
{
//Book
Book Book1 = new Book();
Book1.BookNum = 123456;
Book1.BookTitle = "Harry Potter 1";
Book1.BookAuthor = "JK Rowling";
Book1.BookPrice = 5.95;
//Text Book
TextBook TBook1 = new TextBook();
TBook1.BookNum = 123436;
TBook1.BookTitle = "Harry Potter 2";
TBook1.BookAuthor = "JK Rowling";
TBook1.BookPrice = 5.95;
TBook1.BookGrade = "A";
//Coffee Table Book
CoffeeTableBook CBook1 = new CoffeeTableBook();
CBook1.BookNum = 123136;
CBook1.BookTitle = "Harry Potter 7";
CBook1.BookAuthor = "JK Rowling";
CBook1.BookPrice = 95.95;
Book[] bookArray = new Book[3] { Book1, TBook1, CBook1 };
for (int i = 0; i < bookArray.Length; i++)
{
if (bookArray[i].GetType() == typeof(TextBook))
{
Console.WriteLine("{0} {1} {2} {3} {4}", bookArray[i].BookNum, bookArray[i].BookTitle, bookArray[i].BookAuthor, bookArray[i].BookPrice, bookArray[i].BookGrade);//'Book' does not contain a defination for 'BookGrade'..
}
else
{
Console.WriteLine("{0} {1} {2} {3} {4}", bookArray[i].BookNum, bookArray[i].BookTitle, bookArray[i].BookAuthor, bookArray[i].BookPrice, "N/A");
}
}
}
}
}
您需要强制转换到if bookArray[i]中的特定类型 例如:
我通常会建议使用所描述的新的交换功能模式,但我不想干涉你的老师。另外,你可以重新定义你的类,避免在
class Book
{
public int BookNum { get; set; }
public string BookTitle { get; set; }
public string BookAuthor { get; set; }
public double BookPrice { get; set; }
public string BookGrade = "N/A";
}
class TextBook : Book // must be priced between $20.00 and $80.00
{
const double MIN_PRICE = 20;
const double MAX_PRICE = 80;
public string BookGrade { get; set; }
new public double BookPrice
{
set
{
if (value < MIN_PRICE)
{
base.BookPrice = MIN_PRICE;
}
else if (value > MAX_PRICE)
{
base.BookPrice = MAX_PRICE;
}
else
{
base.BookPrice = value;
}
}
get
{
return base.BookPrice;
}
}
}
class CoffeeTableBook : Book //must be priced between $35.00 and $100.00
{
const double MIN_PRICE = 35;
const double MAX_PRICE = 100;
new public double BookPrice
{
set
{
if (value < MIN_PRICE)
{
base.BookPrice = MIN_PRICE;
}
else if (value > MAX_PRICE)
{
base.BookPrice = MAX_PRICE;
}
else
{
base.BookPrice = value;
}
}
get
{
return base.BookPrice;
}
}
}
您可以重写“toString”方法来设置显示对象的确切方式
class Program
{
class Book
{
public int BookNum { get; set; }
public string BookTitle { get; set; }
public string BookAuthor { get; set; }
public double BookPrice { get; set; }
public override string ToString() //!
{
return string.Format("{0} {1} {2} {3}", this.BookNum, this.BookTitle, this.BookAuthor, this.BookPrice);
}
}
class TextBook : Book // must be priced between $20.00 and $80.00
{
const double MIN_PRICE = 20;
const double MAX_PRICE = 80;
public string BookGrade { get; set; }
new public double BookPrice
{
set
{
if (value < MIN_PRICE)
{
base.BookPrice = MIN_PRICE;
}
else if (value > MAX_PRICE)
{
base.BookPrice = MAX_PRICE;
}
else
{
base.BookPrice = value;
}
}
get { return base.BookPrice; }
}
public override string ToString() //!
{
return base.ToString() + " " + this.BookGrade;
}
}
class CoffeeTableBook : Book //must be priced between $35.00 and $100.00
{
const double MIN_PRICE = 35;
const double MAX_PRICE = 100;
new public double BookPrice
{
set
{
if (value < MIN_PRICE)
{
base.BookPrice = MIN_PRICE;
}
else if (value > MAX_PRICE)
{
base.BookPrice = MAX_PRICE;
}
else
{
base.BookPrice = value;
}
}
get { return base.BookPrice; }
}
}
private static void Main(string[] args)
{
//Book
var book1 = new Book
{
BookNum = 123456,
BookTitle = "Harry Potter 1",
BookAuthor = "JK Rowling",
BookPrice = 5.95
};
//Text Book
var TBook1 = new TextBook
{
BookNum = 123436,
BookTitle = "Harry Potter 2",
BookAuthor = "JK Rowling",
BookPrice = 5.95,
BookGrade = "A"
};
//Coffee Table Book
var CBook1 = new CoffeeTableBook
{
BookNum = 123136,
BookTitle = "Harry Potter 7",
BookAuthor = "JK Rowling",
BookPrice = 95.95
};
var bookArray = new Book[] {book1, TBook1, CBook1};
foreach (Book t in bookArray)
{
Console.WriteLine(t); //! i.e Console.WriteLine(t.ToString());
}
}
您可以用较短的格式重写for循环,如下所示:
string output;
foreach (Book bk in bookArray)
{
output = string.Format(
"{0} {1} {2} {3} {4}",
bk.BookNum,
bk.BookTitle,
bk.BookAuthor,
bk.BookPrice,
(bk is TextBook)
? (bk as TextBook).BookGrade
: "N/A");
Console.WriteLine(output);
}
想象一下,如果您添加更多从Book派生的类,您的代码将变得非常笨拙
if(book.GetType() == typeof(TextBook))
{
}
if(book.GetType() == typeof(CoffeeTableBook))
{
}
if(book.GetType() == typeof(AnotherBookType))
{
}
if(book.GetType() == typeof(MagicalSpellsBook))
{
}
if(book.GetType() == typeof(Whatever))
{
}
如果实际显示书籍的代码发挥作用,情况会变得更糟
你能做些什么来解决这个问题?首先介绍一个图书渲染器
现在,您可以为从Book派生的每种类型创建渲染器,例如
当然,这是有代价的,但是单个类保持整洁。此外,还可能需要将您的书籍呈现到不同的系统。引入这些呈现器允许您交换实现,而无需更改实际的类。您也不会将业务逻辑与Book类混淆——在本例中,它们是这样的,因为它们会对presentation执行价格检查,如果您只是为了实现所需的presentation而过度使用字符串,您就会这样做。我试过TextBookArray[I]。BookGrade而不是TextBookArray[I].BookGrade cheers将更改BookGrade的类型而不是bookArray[i]:
class Program
{
class Book
{
public int BookNum { get; set; }
public string BookTitle { get; set; }
public string BookAuthor { get; set; }
public double BookPrice { get; set; }
public override string ToString() //!
{
return string.Format("{0} {1} {2} {3}", this.BookNum, this.BookTitle, this.BookAuthor, this.BookPrice);
}
}
class TextBook : Book // must be priced between $20.00 and $80.00
{
const double MIN_PRICE = 20;
const double MAX_PRICE = 80;
public string BookGrade { get; set; }
new public double BookPrice
{
set
{
if (value < MIN_PRICE)
{
base.BookPrice = MIN_PRICE;
}
else if (value > MAX_PRICE)
{
base.BookPrice = MAX_PRICE;
}
else
{
base.BookPrice = value;
}
}
get { return base.BookPrice; }
}
public override string ToString() //!
{
return base.ToString() + " " + this.BookGrade;
}
}
class CoffeeTableBook : Book //must be priced between $35.00 and $100.00
{
const double MIN_PRICE = 35;
const double MAX_PRICE = 100;
new public double BookPrice
{
set
{
if (value < MIN_PRICE)
{
base.BookPrice = MIN_PRICE;
}
else if (value > MAX_PRICE)
{
base.BookPrice = MAX_PRICE;
}
else
{
base.BookPrice = value;
}
}
get { return base.BookPrice; }
}
}
private static void Main(string[] args)
{
//Book
var book1 = new Book
{
BookNum = 123456,
BookTitle = "Harry Potter 1",
BookAuthor = "JK Rowling",
BookPrice = 5.95
};
//Text Book
var TBook1 = new TextBook
{
BookNum = 123436,
BookTitle = "Harry Potter 2",
BookAuthor = "JK Rowling",
BookPrice = 5.95,
BookGrade = "A"
};
//Coffee Table Book
var CBook1 = new CoffeeTableBook
{
BookNum = 123136,
BookTitle = "Harry Potter 7",
BookAuthor = "JK Rowling",
BookPrice = 95.95
};
var bookArray = new Book[] {book1, TBook1, CBook1};
foreach (Book t in bookArray)
{
Console.WriteLine(t); //! i.e Console.WriteLine(t.ToString());
}
}
string output;
foreach (Book bk in bookArray)
{
output = string.Format(
"{0} {1} {2} {3} {4}",
bk.BookNum,
bk.BookTitle,
bk.BookAuthor,
bk.BookPrice,
(bk is TextBook)
? (bk as TextBook).BookGrade
: "N/A");
Console.WriteLine(output);
}
if(book.GetType() == typeof(TextBook))
{
}
if(book.GetType() == typeof(CoffeeTableBook))
{
}
if(book.GetType() == typeof(AnotherBookType))
{
}
if(book.GetType() == typeof(MagicalSpellsBook))
{
}
if(book.GetType() == typeof(Whatever))
{
}
class BookRenderer
{
List<ISpecificBookRenderer> specificBookRenderers = ...; // pass via constructor
public void RenderBook(Book b)
{
var matchingRenderer = specificBookRenderers.First(r => r.BookType == b.GetType());
matchingRenderer.RenderBook(b);
}
}
interface ISpecificBookRenderer
{
Type BookType { get; }
void RenderBook(Book b);
}
class TextBookRenderer
{
public Type BookType => typeof(TextBook);
public void RenderBook(Book b)
{
if(b is TextBoox textBook)
{
// output TextBook value
}
throw new ArgumentException("Passed book is not a TextBook", nameof(b));
}
}