【问题标题】:Using virtual in C# [duplicate]在 C# 中使用虚拟 [重复]
【发布时间】:2013-10-01 18:31:57
【问题描述】:

virtual 在 C# 中的用途是什么?使用它的正确方法和理由是什么?

例如,public virtual ICollection<Order> Orders { get; set; }Client 类中定义集合订单(例如,在餐厅或其他地方)。你为什么要在这里使用虚拟?它有什么作用,一般正确的使用方法是什么?

【问题讨论】:

标签: c# oop virtual


【解决方案1】:

虚拟函数并非特定于 C#。它们允许算法在不知道Child 的实现细节的情况下,对特定基类Parent 的对象进行操作,继续对从Parent 派生的类Child 的对象进行操作。

一个简单的例子:Object.ToString。我们可能有一个带有各种控件的表单。如果我们想检查我们有哪些控件,我们可以这样做:

foreach (control in form.Controls)
  Debug.Print(control.ToString())

每个控件都属于某个类,该类在其祖先树中始终具有Object 类,并且可以覆盖ToString 以提供其自己的有意义的实现。但是,我们不需要知道我们在表单上使用的每个控件类的ToString 的实现细节,就可以完成这项工作。我们甚至不需要知道ToString 是否已被覆盖。

有时,类库的设计者故意将类方法标记为虚拟方法,尽管乍一看默认方法实现是非常通用的。这样做是为了未来的灵活性。您的public virtual ICollection<Order> Orders { get; set; } 示例可能就是这种情况。将来可能从Client 类派生新类的开发人员可以选择为Orders 属性提供替代行为。例如,负责处理订单的基本库中的代码将继续在二进制级别上与此类新类一起正常工作。不需要重新编译基础库。

【讨论】:

    【解决方案2】:

    将类的属性/方法/等定义为虚拟使您能够在派生类中覆盖它。

    为什么要将它与“在餐厅或其他地方说的客户类”一起使用,取决于您如何区分不同的客户。如果一个客户子组总是订购相同的东西,例如,您可以覆盖其派生类(来自客户端)中的 Orders 属性以始终返回该特定订单。

    【讨论】:

      【解决方案3】:

      MSDN 有答案http://msdn.microsoft.com/en-us/library/9fkccyh4.aspx

      virtual 关键字用于修改方法、属性、索引器或事件声明,并允许在派生类中对其进行覆盖。例如,这个方法可以被任何继承它的类覆盖:

      如果您要创建一个从客户端继承的子类,您将能够覆盖此方法并将其设为只读,或修改 get 子句,限制添加的集合的大小.....等

      【讨论】:

        猜你喜欢
        • 2021-03-26
        • 2019-01-01
        • 2020-07-06
        • 1970-01-01
        • 1970-01-01
        • 2015-09-29
        • 2011-03-03
        • 2017-08-13
        • 1970-01-01
        相关资源
        最近更新 更多