22

我正在学习 J Galloway 的教程“Professional ASP.NET MVC 3”。在本教程中,Jon 向我们展示了如何构建 MVC 音乐商店。

我正在创建 CS 类以首先使用 EF 代码对数据进行建模。

我书中所有的例子,public virtual int property {get; set; }都是用的,不做解释。虚拟一词无处不在。

在网络的其他地方,我没有看到任何形式的一致使用的术语虚拟。

谁能给我解释一下:

  1. 在此特定上下文中“虚拟”一词的目的
  2. 有必要使用“虚拟”吗?
  3. 为什么有些人使用“虚拟”而其他人不使用?
  4. 为什么有些人在定义外键时只使用“虚拟”?
  5. “虚拟”一词的最佳实践用法是什么?

提前谢谢了

4

7 回答 7

12

为了真正理解virtual关键字,您通常需要阅读多态性

多态性通常被称为继封装和继承之后的面向对象编程的第三大支柱。多态性是一个希腊词,意思是“多形”,它有两个不同的方面:

  1. 在运行时,派生类的对象可以在方法参数和集合或数组等位置被视为基类的对象。发生这种情况时,对象的声明类型不再与其运行时类型相同。

  2. 基类可以定义和实现虚方法,派生类可以覆盖它们,这意味着它们提供自己的定义和实现。在运行时,当客户端代码调用该方法时,CLR 会查找对象的运行时类型,并调用该虚拟方法的覆盖。因此,在您的源代码中,您可以调用基类上的方法,并导致执行派生类的方法版本。

一旦你更好地理解了这些概念,你就可以确定你从书中创建的方法是否需要virtual

于 2012-10-01T18:27:18.650 回答
7

谁能给我解释一下:

  1. 在此特定上下文中“虚拟”一词的目的

    这里的其他用户很好地回答了这个问题,并提供了很好的参考。

  2. 有必要使用“虚拟”吗?

    这取决于。有时是必要的,有时是多余的。

  3. 为什么有些人使用“虚拟”而其他人不使用?

    他们在需要时使用它,或者在他们认为可能需要时使用它。

  4. 为什么有些人在定义外键时只使用“虚拟”?

    在为实体框架和 NHibernate 等对象关系映射工具定义外键时,virtual通常是必要的,因为这些 ORM 工具会动态创建一个继承自您的类的新类。这些“动态代理”类覆盖您的virtual属性,以提供维护外键一致性所需的额外行为。在 NHibernate 的情况下,所有属性(不仅仅是外键)都必须标记为virtual。这是因为 NH 动态代理添加了自定义行为来决定从数据库中检索模型上的哪些属性,以及避免加载哪些属性。

  5. “虚拟”一词的最佳实践用法是什么?

    当您打算在更派生的类中覆盖成员(方法或属性)时使用它。不要在标有 的类中使用它们sealed

于 2012-10-01T22:12:56.540 回答
4

好的,所以术语虚拟,基本上意味着“可覆盖”(具有基本实现),但不是抽象的(意味着没有原始实现)。

如果您希望某人覆盖您的方法或属性,而不是“隐藏”它,则“虚拟”关键字是必需的。

所以这一切都适用于继承和多态。派生类可以覆盖虚拟方法并使其成为自己的实现(甚至在该方法中调用基实现)。通过覆盖,您可以保证您的新方法将以多态方式调用,而不是基本实现。

相反,使用“new”关键字,您可以“隐藏”数据成员和方法。这也将允许您进行自己的实现,但不会多态地执行您的新实现,它将使用基类实现。

虚拟关键字

使用 Override 和 New 关键字进行版本控制(C# 编程指南)

于 2012-10-01T18:33:32.230 回答
4

他在模型中使用 virtual 关键字的原因是启用Change Tracking 代理。这是实体框架特有的东西(编辑:还有 NHibernate,可能还有其他任何形式,感谢@danludwig),它允许 EF 自动管理您映射到数据库的实体。

来自 MSDN:

映射到数据模型中实体类型的属性的每个属性都必须具有非密封(Visual Basic 中的 NotOverridable)、公共和虚拟(Visual Basic 中的可替代)get 和 set 访问器。

于 2012-10-01T19:29:09.613 回答
1

请参阅虚拟(C# 参考) 。添加virtual关键字允许在派生类中覆盖该属性,这很可能在您构建 MVC 应用程序的通用基类时。

于 2012-10-01T18:29:07.600 回答
0

来自文档

virtual 关键字用于修改方法、属性、索引器或事件声明,并允许在派生类中对其进行覆盖。

因此,如果您需要隐藏旧功能并添加新功能,您可以使用 virtual。根据开发新的模块和架构,不同的应用程序需要不同的要求。

见这里http://msdn.microsoft.com/en-us/library/9fkccyh4(v=vs.80).aspx

于 2012-10-01T18:27:56.497 回答
0

Virtual 确保继承的子类通过强制它们覆盖属性来覆盖基类。如果没有它的 virtual 关键字,子对象就不能覆盖基本功能。

于 2012-10-01T18:37:06.597 回答