【问题标题】:Polymorphism using switch statement使用 switch 语句的多态性
【发布时间】:2015-04-21 14:48:55
【问题描述】:

我们有一些文档类型:

class Document
{
    public void virtual Print()
}

class PDF : Document
{
    public void override Print()
    {
        Console.WriteLine("PDF Printed");
    }
}

class Excel : Document
{
    public void override Print()
    {
        Console.WriteLine("Excel Printed");
    }
}

假设我们有一个文档列表(文档对象),我们在所有文档上调用虚函数 Print()。

foreach(Document doc in DocumentsList)
{
    doc.Print();
}

我知道多态是一种非常复杂的实现方式,但是我们真的可以使用 switch 语句来做同样的事情吗?我和一个人争论了很久,他说这是可能的。是吗?

【问题讨论】:

  • 为什么不可能?只会更烦人。
  • 没有多态一切皆有可能。但它会看起来很尴尬。
  • 看起来这篇文章可能有你要找的东西:stackoverflow.com/questions/298976/… 但我同意其他人的观点,多态性几乎肯定是首选的方法。
  • 对于图灵完备语言,“可能”的通常答案是“是”。
  • 如果有人能正确阅读这个问题,我已经提到多态性是一种复杂的方式。我觉得这个问题被否决,而答案是肯定或否定的却被投赞成票,这很荒谬

标签: c# inheritance switch-statement polymorphism


【解决方案1】:

是的,你可以,当然你可以在每次迭代时询问列表的成员,并且有很多技术可以实现这一点(例如属性、内部类型字段等)。

事实上,您在 C# 中所做的所有事情都可以在 Assembler 中完成! 但是,我几乎看不出避免使用 OOP 的优势有什么好处。

【讨论】:

    【解决方案2】:

    是的,您始终可以使用开关(或 if-else 链)来询问类型。您可以在对象中保留文档类型信息,例如作为枚举,并在开关中使用它。

    为什么你不应该这样做?因为在添加新的派生类型时必须扩展所有这些开关。

    为避免这种情况,您可以实现一些更自动化的方法:拥有一个指向函数(或 C# 中的委托)的指针列表,您可以使用适合该特定对象的函数(例如,print对于 PDF 文件,委托将指向 print_pdf(),对于 Excel 文件,则指向 print_excel())。嘿,你已经手工制作了一个穷人的多态性。

    多态的好处是代码使用多态对象可以是类型不可知的。它不知道对象实际具有什么精确类型,也不想知道。在编写代码处理对象时,精确的类型可能不存在。所有详细信息都隐藏在类型中,非常便于维护。

    【讨论】:

    • @tobi303 也是这么说的,我想
    【解决方案3】:

    这是一个有趣的问题,因为使用 switch 的示例通常用于演示您通常不想这样做的方式。

    除了使用继承之外,您还可以使用这样的文档类:

    class Doc {
        public: 
            enum DocType{PDF,EXCEL}
        private:
            DocType docType;
    }
    

    然后你只需使用

    switch (doc.getDocType()){
        ...etc...
    }
    

    但是,通常使用继承更好的原因有几个。例如,想象一下,您想添加另一种文档类型。然后,您不仅必须添加另一个枚举字段,而且(这就是大问题)您还必须更改使用 Document 类的所有代码中的每个 switch 语句。这很烦人,通常你不想这样做。

    【讨论】:

    • 抱歉忽略了您答案的最后一部分(在我下线之前)。
    【解决方案4】:

    多态是解决这个问题的方法。如果选择switch 语句,则需要使用Reflectionis 关键字来确定要调用哪个对象的Print()

    【讨论】:

    • 为什么需要反思?你既不需要反射也不需要is关键字。
    猜你喜欢
    • 1970-01-01
    • 2010-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-19
    • 2011-07-02
    • 2011-06-09
    • 1970-01-01
    相关资源
    最近更新 更多