C# 显示不同对象的数组c(类继承)

C# 显示不同对象的数组c(类继承),c#,class,object,inheritance,C#,Class,Object,Inheritance,我的代码有问题。我是一个新的继承者,到目前为止,我只听过一次关于它的讲座,非常感谢大家的帮助。有人给了我这个问题,我想我已经差不多解决了。创建一个Book类,添加两个子类。全部显示。加上其他东西,但这是核心问题 当我试图在for循环中显示每个对象及其信息时,我不知道如何访问教科书的BookGrade。我做了一系列的书,把所有的东西都放在里面。我知道这不对,但我不知道该怎么办。我试过制作一系列这样的教科书 TextBook[] bookArray = new TextBook[3] { Book1

我的代码有问题。我是一个新的继承者,到目前为止,我只听过一次关于它的讲座,非常感谢大家的帮助。有人给了我这个问题,我想我已经差不多解决了。创建一个Book类,添加两个子类。全部显示。加上其他东西,但这是核心问题

当我试图在for循环中显示每个对象及其信息时,我不知道如何访问教科书的BookGrade。我做了一系列的书,把所有的东西都放在里面。我知道这不对,但我不知道该怎么办。我试过制作一系列这样的教科书

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