惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

爱范儿
爱范儿
博客园_首页
W
WeLiveSecurity
S
Secure Thoughts
S
Security @ Cisco Blogs
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Hugging Face - Blog
Hugging Face - Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
H
Hacker News: Front Page
Project Zero
Project Zero
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
U
Unit 42
N
News and Events Feed by Topic
N
News and Events Feed by Topic
Hacker News - Newest:
Hacker News - Newest: "LLM"
Forbes - Security
Forbes - Security
T
Tor Project blog
I
Intezer
B
Blog
F
Full Disclosure
Security Archives - TechRepublic
Security Archives - TechRepublic
F
Fortinet All Blogs
Schneier on Security
Schneier on Security
T
Threat Research - Cisco Blogs
AI
AI
Google DeepMind News
Google DeepMind News
L
LINUX DO - 最新话题
Cloudbric
Cloudbric
L
Lohrmann on Cybersecurity
WordPress大学
WordPress大学
博客园 - 聂微东
雷峰网
雷峰网
P
Privacy International News Feed
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
PCI Perspectives
PCI Perspectives
Y
Y Combinator Blog
Spread Privacy
Spread Privacy
Simon Willison's Weblog
Simon Willison's Weblog
罗磊的独立博客
Vercel News
Vercel News
A
Arctic Wolf
The Register - Security
The Register - Security
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Microsoft Azure Blog
Microsoft Azure Blog
H
Heimdal Security Blog
Know Your Adversary
Know Your Adversary
P
Proofpoint News Feed
C
Cybersecurity and Infrastructure Security Agency CISA
P
Proofpoint News Feed

博客园 - 紫微星

Python ImportError: No module named arcgisscripting ENVI遥感影像处理实用手册PDF下载 卡巴斯基许可Key需求登记表 ArcGIS Desktop 9.3 中文运行环境|中文补丁 胡适:赠与今年的大学毕业生 ArcMap打不开且出现提示(Hostname:Not_Set)的解决方法 QQ超级群问题反馈 “GIS空间分析-使用ArcGIS”课程资料完整打包下载,感谢杨克诚老师! ArcGIS 9.3 下载(包含ArcGIS Desktop、ArcGIS Engine、ArcGIS Server、ArcSDE、workstation) ArcGIS中查看metadata显示"warning+乱码"的解决方法 [请您去投票]ESRI中国社区2008年度优秀会员评选 [新年快乐!] Modeling Our World三版合集 下载[2009-4-27更新] ADO.NET入门学习备忘 GIS界首个超级QQ群——“GIS人@E家”,欢迎GIS朋友们加入! 深入研究VS2008中的JavaScript编辑调试器 AE初学的一点理解及有关QI(接口查询) 引用与using的什么区别 平时遇到的GISblog收集 平时遇到的C#和VS问题及解决方法记录 - 紫微星 - 博客园
控件和组件的差别[转]
紫微星 · 2008-08-03 · via 博客园 - 紫微星
我正在学习 Microsoft .NET 框架,不太理解控件和组件之间的差别。我知道这些术语可以互用,但什么时候从 Control 派生,什么时候从 Component 派生呢?

Linda Berno  

好问题!简单说来,控件就是具有用户界面的组件。要说的具体一点,就得回顾早期 Windows 的历史根源,当时控件指任何子窗口——按钮、列表框、编辑框或者某个对话框中的静态文本。从概念上讲,这些窗口——控件——类似用来操作收音机或小电器的旋钮和按钮。随着控件数量的增加(组合框、日期时间控件等等),控件逐渐成为子窗口的代名词,无论是用在对话框中还是用在其它种类的主窗口中。没过多久 BASIC 程序员开始编写他们自己专用的控件,自然而然地人们便想到共享这些控件。共享代码的方法之一是通过磁盘拷贝,但那样显然效率低下。必须要有一种机制使开发者建立的控件能够在其它程序员的应用中轻而易举地插入,这便是VBA控件,OLE控件,OCX和最后ActiveX 控件的动机。
  这就是控件和组件之间产生混淆之所在。因为为了解决控件的可复用问题,所有这些技术必须首先解决更为一般的组件重用问题。(COM,如果你还记得它的话,意思是组件对象模型)。在软件行话中,组件这个术语指任何可复用的对象或任何可与其它对象交互的代码体。子程序的发明,曾经一度成为程序员趋之若鹜的软件工程圣杯:一种统一的编程理论,它使程序员从基本构建块——也就是用所选语言编写的各种组件建立大型系统。从子程序演变到OOP,到DLLs,再到COM,再到.NET框架的每一种新的编程范例都代表了一种不同的提供可重用性的方案。VBX使用DLLs的固化名称。COM使用接口和IUnknown。.NET框架使用微软的中间语言(MSIL)层和公共语言运行时(CLR)来提供统一的粘合。

因此,控件是组件的一个主要样本(并且历史上曾驱动着组件的开发),控件又不仅仅是唯一的一种组件。组件不需要显示任何信息或用户界面。组件可能实现科学计算,收集性能数据,计算1971年1月1日到现在的毫秒数,仰或是读取布什总统竞选活动保险箱里的美金数。Figure 4 显示了 Visual Studio .NET 中的非控件组件例子。


Figure 4 组件

在 .NET 框架中,术语控件和组件为 .NET 赋予了专门的意义。Component 类为被用于设计层面的对象如 Windows Forms Designer (Windows 窗体设计器)或 Web Forms Designer (Web 窗体设计器)提供了基本实现。某个 Component 是任何可以被拽到某个窗体的任何东西。Component 类实现IComponent,ISite 和 IContainer。这些接口比起其来自 OLE 时期的 COM 堂兄弟要简单得多。 IContainer 比起带有 Add/Remove 方法的组件列表以及组件属性来要稍微复杂一点,它获得的组件是一个 ComponentCollection (组件集合)。
IComponent 从 IDisposable 派生而来,并且只有一个属性,Site,获取组件的ISite接口。Component 可能有,也可能没有Site。ISite 有四个属性,其中包括Name和DesignMode,它控制该组件是否处于——还能是什么?——设计模式。ISite 派生于另一个接口,IServiceProvider,它只有一个方法,GetService。在COM中,IServiceProvider 类似 QueryInterface——用它可以通过ID来查询某个对象的接口,但是与 QueryInterface 不同的是该对象本身不用去实现这个接口,它仅仅知道在哪里和如何获取它即可。同样,在.NET框架中,IServiceProvider 是一种获取其它接口或对象的通用方法——服务——对象不用实现它就知道的一种服务。
  .NET框架使得编写可复用组件轻松自如,不再需要 IDL,不再需要类型定义语言,不再需要费力的设计时支持。通过反射(reflection)的魔法,CLR 从代码本身就已经知道了该知道的一切,所有的类都在掌控之中。为了添加设计时支持,你只要用额外的设计器标记你的属性即可。例如,在托管C++中:

// in CMyControl
            [Category(S"Appearance")]
            [Description(S"Specifies widget foreground color.")]
            _property Color get_ForeColor() { ... }
            _property void set_ForeColor(Color value) { ... }

现在窗体设计器在“外观”(Appearance)中列出你的 ForeColor 属性并使用帮助描述(Description)。有关设计时属性的更多内容,请参考.NET框架文档中的“组件的设计时属性”


Figure 5 类层次结构

Figure 5 显示了.NET框架中的类层次结构,它能说明上述讨论的问题。正如你所看到的,Control 从
Component 派生而来。这是用另外一种方式来说明控件即组件(反之则不然)。更具体地讲,控件是一个用用户界面的组件——能绘制东西并能与用户交互。Control 类还是所有托管窗口类的基类——窗体、按钮、栅格、面板、工具栏等等。Control 类是定义 WndProc 和 ClientSize 以及所有标准窗口事件如 GotFocus 和 Click 的地方。Web控件(System.Web.UI.Control)也是组件,不过从严格的意义上讲,它不是从 System.ComponentModel.Component 派生的。(对于 Web 控件,其名字空间为 System.Web.UI,Control 本身实现 IComponent。)
  除了实现 IComponent 之外,System.ComponentModel.Component 还提供了所有组件需要的列集支持,但它是通过从 MarshalByRefObject 派生来实现的。如果想生成一个值列集组件,可以从 MarshalByValueComponent 派生(它实现了 IComponent,IDisposable 和 IServiceProvider)。System.Data.DataColumn,DataSet 和 DataTable 都是是值列集组件的例子。这些对象跨机器/进程边界传递其实际数据。
  如果你正在编写其他人也能用窗体设计器拖拽到其窗体的可重用的小组件,那么你必须从 Component 派生。如果你的小组件还具备用户界面——能创建窗口,绘画或与用户交互——那么就应该从 Control 派生。明白了吗?

向 Paul 提问和评论请发到 cppqa@microsoft.com.