类、组件和控件

来源:百度文库 编辑:神马文学网 时间:2024/04/29 16:15:10
.NET Framework
类、组件和控件
本主题对组件和控件进行了定义;此处进行的讨论可以帮助您决定何时实现一个是组件或控件的类。
以下列表为实施者提供了全面的指南。
如果您的类使用外部资源但不用于设计图面,则实现System.IDisposable,或者从直接或间接实现IDisposable 的类派生。
如果您的类要用于设计图面(如 Windows 窗体或 Web 窗体设计器),则实现System.ComponentModel.IComponent,或者从直接或间接实现IComponent 的类派生。请注意,IComponent 扩展 IDisposable,因此 IComponent 类型始终是 IDisposable 类型。与不是 IComponent 的 IDisposable 类型相比,IComponent 类型的性能系统开销要小。但这一不足通常可由在设计时和运行时安置 IComponent 的能力来弥补。(在本主题的后面部分将对该安置功能进行说明)。
如果希望类可设计(在设计图面上使用)并且可按引用封送,可从System.ComponentModel.Component 派生。Component 是按引用封送的 IComponent 类型的基实现。
如果希望可设计的类可按值封送,可从System.ComponentModel.MarshalByValueComponent 派生。MarshalByValueComponent 是按值封送的 IComponent 类型的基实现。
如果希望向对象模型层次中引入 IComponent 类型,但由于单次继承的原因而不能从 Component 或 MarshalByValueComponent 之类的基派生,请实现 IComponent。
如果需要提供用户界面的可设计类,则该类是控件。控件必须直接或间接从下列基控件类之一派生:System.Windows.Forms.Control 或System.Web.UI.Control。
注意
如果您的类既不是可设计类,也不保存外部资源,则不需要 IComponent 或 IDisposable 类型。
下面是组件、控件、容器和站点的定义。
组件
在 .NET Framework 中,组件是指实现System.ComponentModel.IComponent 接口的一个类,或从实现 IComponent 的类中直接或间接派生的类。在编程中,“组件”这个术语通常用于可重复使用并且可以和其他对象进行交互的对象。.NET Framework 组件满足这些一般要求,另外还提供诸如控制外部资源和设计时支持等功能。
控制外部资源
IComponent 接口扩展 IDisposable 接口,后者在其协定中有一个名为Dispose 的方法。在其 Dispose 方法实现中,组件必须显式释放外部资源。与垃圾回收过程中发生的默认、不确定的清理相比,这提供了一个确定的方法来释放资源。开发人员必须在整个包容层次结构中传播 Dispose 以确保组件的子级同时释放资源。另外,派生的组件必须调用其基类的 Dispose 方法。
注意
即使通过 Dispose 提供对资源的显式控制,也应该始终通过终结器(析构函数)提供隐式清理,以防用户未能对您的组件调用 Dispose 时资源永久泄漏。
下面的示例显示了在基组件和在派生的组件中实现 Dispose 的方式。
C#
复制代码
public class BaseComponent : IComponent {// IComponent extends IDisposable.public void Dispose() {Dispose(true);GC.SuppressFinalize(this);}protected virtual void Dispose(bool disposing) {if (disposing) {// Free other state (managed objects).}// Free your own state (unmanaged objects).}// Simply call Dispose(false).~BaseComponent(){Dispose (false);}}// Derived component.public class DerivedComponent : BaseComponent {protected override void Dispose(bool disposing) {if (disposing) {// Free other state.}// You must invoke the Dispose method of the base class.base.Dispose(disposing);// Free your own state....}// No finalizer/destructor.// No Dispose() method.}
Visual Basic
复制代码
‘ Design pattern for a base class.Public Class BaseComponentImplements IComponent‘ Implement IDisposablePublic Overloads Sub Dispose()Dispose(True)GC.SuppressFinalize(Me)End SubProtected Overloads Overridable Sub Dispose(disposing As Boolean)If disposing Then‘ Free other state (managed objects).End If‘ Free your own state (unmanaged objects).‘ Set large fields to null.End SubProtected Overrides Sub Finalize()‘ Simply call Dispose(False).Dispose (False)End SubEnd Class‘ Design pattern for a derived component.Public Class DerivedComponentInherits BaseComponentProtected Overloads Overrides Sub Dispose(disposing As Boolean)If disposing Then‘ Release managed resources.End If‘ Release unmanaged resources.‘ Set large fields to null.‘ Call Dispose on your base class.Mybase.Dispose(disposing)End Sub‘ The derived class does not have a Finalize method‘ or a Dispose method with parameters because it inherits‘ them from the base class.End Class
设计时支持
在 .NET Framework 中,组件的一个重要功能就是它们是可设计的,这意味着作为组件的类可用于快速应用程序开发 (RAD) 环境(如 Visual Studio)中。可将组件添加到 Visual Studio 的工具箱中,也可将组件拖放到某个窗体上,还可以在设计图面上对组件进行操作。请注意,对 IComponent 类型的基本设计时支持已经内置于 .NET Framework 中;组件开发人员无须进行额外的工作就可利用基本设计时功能。
有关设计时支持的更多信息,请参见组件的设计时属性 (Attribute) 和扩展设计时支持。
承载组件
组件可以被放置(承载)在一个容器(本主题稍后部分进行了定义)中。当组件被放置后,它通过其站点(本主题稍后部分进行了定义)与容器进行交互并能够通过站点从其容器查询并得到服务。为了确保容器拆卸后资源被释放,容器必须实现IDisposable 接口。在其 Dispose 方法的实现中,容器必须释放它保留的所有资源,并调用它包含的每个组件的 Dispose 方法。
包容是逻辑上的,不需要可视的表示形式。放置数据库组件的中间层容器就是非可视包容的一个示例。可在 Visual Studio 的 Windows 窗体设计器和 Web 窗体设计器中找到可视包容。可视化设计图面是承载窗体组件(Web 窗体中的页组件)的容器。
封送组件
组件可以是可远程控制的或不可远程控制的。可远程控制的组件由引用或值进行封送。封送涉及跨边界(如应用程序域(轻量进程)、进程、甚至是计算机)发送对象。当对象由引用封送时,会创建一个代理对该对象进行远程调用。当对象由值进行封送时,跨相关边界发送该对象的一个序列化的副本。
以下可远程控制的组件应该由引用封送:封装系统资源的可远程控制组件,较大的可远程控制组件或作为单个实例存在的可远程控制组件。由引用封送的组件的基类是System.ComponentModel.Component。该基类实现 IComponent 并从MarshalByRefObject 派生。.NET Framework 类库中的许多组件从 Component 派生,包括System.Windows.Forms.Control(Windows 窗体控件的基类)、System.Web.Services.WebService(使用 ASP.NET 创建的 XML Web 服务的基类)和System.Timers.Timer(生成递归事件的类)。
仅保留状态的可远程控制组件应该由值封送。由值封送的组件的基类是System.ComponentModel.MarshalByValueComponent。该基类实现 IComponent 并从Object 派生。.NET Framework 类库中只有少量组件从 MarshalByValueComponent 派生。所有此类组件都在System.Data 命名空间中(DataColumn、DataSet、DataTable、DataView 和DataViewManager)。
注意
按值和按引用封送的对象的基类分别是 Object 和 MarshalByRefObject,但对应的派生类名为 MarshalByValueComponent 和 Component。命名方案背后的逻辑是越常用的类型,其名称就越简单。
如果不对组件进行远程控制,则不要从 Component 的基实现派生,而应直接实现 IComponent。
有关对象远程控制的更多信息,请参见.NET 远程处理概述。
控件
控件是提供(或实现)用户界面 (UI) 功能的组件。.NET Framework 为控件提供两个基类:一个用于客户端 Windows 窗体控件,另一个用于 ASP.NET 服务器控件。它们是System.Windows.Forms.Control 和System.Web.UI.Control。.NET Framework 类库中的所有控件直接或间接从这两个类派生。System.Windows.Forms.Control 从 Component 派生,本身提供 UI 功能。System.Web.UI.Control 实现 IComponent 并提供可在其上轻松添加 UI 功能的基础结构。
注意
每个控件都是一个组件,但并不是每个组件都是控件。
容器和站点
如果您正在为 Windows 窗体或 Web 窗体页(ASP.NET 页)开发组件和控件,则不需要实现容器或站点。Windows 窗体和 Web 窗体的设计器就是 Windows 窗体和 ASP.NET 服务器控件的容器。容器向放置在其中的组件和控件提供服务。在设计时,控件放置在设计器中并从设计器获得服务。为了保持完整性,以下给出了容器和站点的定义。
Container
容器是一个实现System.ComponentModel.IContainer 接口的类,或从实现该接口的类派生的类。容器在逻辑上包含一个或多个组件,这些组件叫做容器的子组件。
Site
站点是一个实现System.ComponentModel.ISite 接口的类,或从实现该接口的类派生的类。站点由容器提供,用来管理其子组件及与子组件进行通信。通常,容器和站点作为一个单元来实现。
请参见