[Web]Eurasia3 支持百万级用户的服务器和框架

mikel阅读(835)

项目名称: Eurasia3
发起时间: 2004年
代码托管:http://code.google.com/p/eurasia
项目介绍:
Eurasia3 是一种能够支持百万级同时在线长连接用户数量的 HTTP 服务器, 或者每秒处理上万次 CGI 请求的常规应用服务器。
Eurasia3 同时也泛指以 Eurasia3 应用服务器为核心的一系列组件形成的应用程序框架, 主要是一个嵌入式对象数据库 MissileDB, 和一个 JavaScript 框架 NJF。
Eurasia3 基于 Stackless Python。
产品信息:
运行平台: 支持 Stackless Python 2.5 的系统, 包括各种嵌入式平台
开发语言: Stackless Python
开源协议: BSD License
项目成员:
沈崴, 高级架构师, 上海,项目发起人。
赖勇浩, 某公司技术负责人,广州。
王健, 某公司技术负责人, 经理, 广州。
魏中华, 项目经理, 广州。
庄上林, 项目经理, 广州。
是什么促使你们发起/开始这个项目?
Eurasia 最初源于某个大型人工智能项目, 是为了解决大量逻辑数据的存储和管理的问题而形成的一个 Web 管理系统, 并发展成一套 AJAX 框架。
而 Eurasia3 项目则是源于一系列关于 Web Game 的尝试。我们试图在浏览器上在不使用任何插件和 Flash 的情况下, 就能实现即时类游戏的效果并维持几十乃至上百万人同时在线, 这最终导致了 Eurasia3 框架的产生。
该项目面向哪些使用群体?
黑客, Web Game 和 Web IM 从业人员, 对前沿技术感兴趣的人以及 Comet 爱好者。
举个例子说明下用户使用您的软件能做什么?
基于浏览器的 MMORPG, 玩家在地图上漫游时所看到的一切都是即时的。
基于浏览器的 Web IM, 服务器能负载传统 IM 服务器那样多的在线人数, 消息发送是即时的, 浏览器用户不需要插件就可以互传文件。
Comet 应用, 服务器程序可以在任何时候使用原生 Python 代码远程调用客户浏览器上的 JavaScript 函数。
在一两百块钱 200-300 MHz 主频的嵌入式系统 (诸如路由器, Stackless Python 官方发行版中已经带有我们贡献的补丁可以使 Stackless Python 运行在这类系统上) 上运行以 Eurasia3 为基础的网站可以接近或达到和常规服务器一样的性能。
您认为有多少人使用这个软件/项目/服务?
至少有四家以上的公司正在使用基于 Eurasia 的软件。
有什么迹象表明您的项目很成功?
尽管 Eurasia3 项目主要是面向黑客的, 并且我们相当低调 ──── 你知道我们主要还是以自己使用为主, 也回馈一下社区, 这并不会带来实际的利益。但是还是吸引了相当多的关注。
尽管 Eurasia3 目前仍然在 alpha4 阶段, 但是从 alpha2 开始我们就已经许多项目在实际使用 Eurasia3 了, 这些产品还是颇令我们满意的。
您觉得最大的惊喜是什么
尽管 Python 的框架已经很多, 我们也不期望 Eurasia3 在将来某一天像 Django 那样流行, 但是对 Eurasia3 感兴趣的人还是相当多, 有些人甚至表示在将来 Eurasia3 正式发布时用它来替代 Django (甚至 Nginx), 这比较意外。
您在该项目中遇到的最大挑战是什么?
最大的挑战是时刻保持领先。尽管目前 Eurasia3 是业内比较尖端的技术, 但是我们知道迟早会有超越 Eurasia3 的技术出现, 在此之前我们会努力保持领先。
您在该项目中认为获得成功的要素有哪些?
黑客的关注和参与。
持续地在正式项目中进行检验。
保证劣质的代码和编程思想不进入项目, 保证代码不膨胀不失控。
您对该项目有哪些期望?
一个使用 Eurasia3 编写的 Web Game, 事实上我们正在着手这件事情, 这在明年或许就会实现。然后就是大家在启动一个很酷的项目或者一个奇怪的想法时会自然而然地想到 Eurasia3。或许这些都不会真的出现, 但对我们也没有损失。
如果您能对项目进行修改,您会改善哪些地方?
文档, 当然了。从 alpha2 开始接口一直在缓慢变化, 到下一个冻结特性的 alpha5 版本或许会有更剧烈的变动, 而文档一直是滞后的。这也导致了许多用户的不满, 当然也包括我自己在内, 因为连我们自己都有许多产品都是基于老版本的。
你们如何来协调项目?
SVN、Gtalk
你们把所有精力都投入在这个软件上,还是有其他的什么工作?
我们大部分人都有自己的公司, 并且正带着自己的团队在做一些看上去很有前途的东西。
那你们一般花多长时间在这个项目上?
每周20小时, 10 小时, 或者 0小时。你知道在没有灵感时与其放一些垃圾代码进去, 还不如不写,
你们用的开发环境是什么
操作系统: Linux (主要是 Ubuntu)
编辑器: vim, gedit
项目里程碑
1999 年 NJF 框架开始设计, 这是 Eurasia 最早的组成部分。
2004 年 Eurasia 项目开始。
2006 年 9 月 Eurasia 2.0.2 版以 BSD License 开源, 年底 Eurasia3 项目开始。
2007 年 12 月 Eurasia 3.0.0 alpha 发布。
2008 年 Eurasia 3.0.0 alpha4 发布。
其他人如何给你们提供建议?
Eurasia3 用户组 http://groups.google.com/group/eurasia-users

[SQL]SQL Server中的视图概念

mikel阅读(1051)

最近项目中发现一个问题,就是按Not in top方法对视图 分页时候如果不指定order by 条件,分页出来的每页结果存在混乱现象,究其原因还是因为视图本身没有类似表一样的默认排序规则,导致数据分页无序读取的,看来还是
对视图不是很了解,特查了下SQL server的帮助,摘要如下:

视图是一个虚拟表,其内容由查询定义。同真实的表一样,视图包含一系列带有名称的列和行数据。视图在数据库中并不是以数据值存储集形式存在,除非是索引视图。行和列数据来自由定义视图的查询所引用的表,并且在引用视图时动态生成。

对其中所引用的基础表来说,视图的作用类似于筛选。定义视图的筛选可以来自当前或其他数据库的一个或多个表,或者其他视图。分布式查询也可用于定义使用多个异类源数据的视图。例如,如果有多台不同的服务器分别存储您的单位在不同地区的数据,而您需要将这些服务器上结构相似的数据组合起来,这种方式就很有用。

通过视图进行查询没有任何限制,通过它们进行数据修改时的限制也很少。

 

标准视图

标准视图组合了一个或多个表中的数据,您可以获得使用视图的大多数好处,包括将重点放在特定数据上及简化数据操作。有关这些好处的详细信息,请参阅使用视图的情况

索引视图

索引视图是被具体化了的视图,即它已经过计算并存储。可以为视图创建索引,即对视图创建一个唯一的聚集索引。索引视图可以显著提高某些类型查询的性能。索引视图尤其适于聚合许多行的查询。但它们不太适于经常更新的基本数据集。有关详细信息,请参阅设计索引视图

分区视图

分区视图在一台或多台服务器间水平连接一组成员表中的分区数据。这样,数据看上去如同来自于一个表。联接同一个 SQL Server 实例中的成员表的视图是一个本地分区视图。

注意:
SQL Server 2005 中包含本地分区视图只是为了实现向后兼容,并且当前不推荐使用。本地分区数据的首选方法是通过已分区表。有关详细信息,请参阅已分区表和已分区索引

如果视图在服务器间联接表中的数据,则它是分布式分区视图。分布式分区视图用于实现数据库服务器联合。联合体是一组分开管理的服务器,但它们相互协作分担系统的处理负

视图通常用来集中、简化和自定义每个用户对数据库的不同认识。视图可用作安全机制,方法是允许用户通过视图访问数据,而不授予用户直接访问视图基础表的权限。视图可用于提供向后兼容接口来模拟曾经存在但其架构已更改的表。还可以在向 Microsoft SQL Server 2005 复制数据和从其中复制数据时使用视图,以便提高性能并对数据进行分区。

着重于特定数据

视图使用户能够着重于他们所感兴趣的特定数据和所负责的特定任务。不必要的数据或敏感数据可以不出现在视图中。

例如,AdventureWorks 示例数据库中的视图 vBikes 允许用户查看当前库存的所有自行车的名称。该视图将从 Product 表中筛选掉除 Name 之外的所有字段,并仅返回自行车成品的名称,而不是自行车配件的名称。

复制代码
Create VIEW vBikes AS
Select DISTINCT p.[Name] FROM Production.Product p
JOIN Production.ProductInventory i ON p.ProductID = i.ProductID
JOIN Production.ProductSubCategory ps
ON p.ProductSubcategoryID = ps.ProductSubCategoryID
JOIN Production.ProductCategory pc
ON (ps.ProductCategoryID = pc.ProductCategoryID
AND pc.Name = N'Bikes')
AND i.Quantity > 0

简化数据操作

视图可以简化用户处理数据的方式。可以将常用联接、投影、UNION 查询和 Select 查询定义为视图,以便使用户不必在每次对该数据执行附加操作时指定所有条件和条件限定。例如,可以将一个用于报表目的且执行子查询、外联接和聚合来从一组表中检索数据的复杂查询创建为视图。视图简化了对数据的访问,因为每次生成报表时无需编写或提交基础查询,而是查询视图。有关对数据进行操作的详细信息,请参阅查询基础知识

尽管不是复杂查询,AdventureWorks 示例数据库中的视图 vBikes 仍允许用户着重于特定数据,而不必构造生成视图所需的 JOIN 子句。

还可以创建用户定义的内联函数,在逻辑上作为参数化视图运行,或者作为在 Where 子句搜索条件或查询的其他部分中含有参数的视图运行。有关详细信息,请参阅内联用户定义函数

提供向后兼容性

视图使您能够在表的架构更改时为表创建向后兼容接口。例如,一个应用程序可能引用了具有以下架构的非规范化表:

Employee(Name, BirthDate, Salary, Department, BuildingName)

若要避免在数据库中重复存储数据,可以通过将该表拆分为下列两个表来规范化该表:

Employee2(Name, BirthDate, Salary, DeptId)

Department(DeptId, BuildingName)

若要提供仍然引用 Employee 中的数据的向后兼容接口,可以删除原有的 Employee 表并用以下视图替换:

复制代码
Create VIEW Employee AS
Select Name, BirthDate, Salary, BuildingName
FROM Employee2 e, Department d
Where e.DeptId = d.DeptId

此时,用于查询 Employee 表的应用程序可以从 Employee 视图中获取它们的数据。如果只从 Employee 中读取,则不必更改应用程序。通过向新视图添加 INSTEAD OF 触发器,将对视图的 Insert、Delete 和 Update 操作映射到基础表,有时也可以支持更新 Employee 的应用程序。有关详细信息,请参阅设计 INSTEAD OF 触发器

自定义数据

视图允许用户以不同方式查看数据,即使在他们同时使用相同的数据时也是如此。这在具有许多不同目的和技术水平的用户共用同一数据库时尤其有用。例如,可创建一个视图以仅检索由客户经理处理的客户数据。该视图可以根据使用它的客户经理的登录 ID 决定检索哪些数据。

导出和导入数据

可使用视图将数据导出到其他应用程序。例如,您可能希望使用 AdventureWorks 数据库中的 Customer 和 SalesOrderHeader 表在 Microsoft Excel 中分析销售数据。为此,可基于 Customer 和 SalesOrderHeader 表创建视图。然后,使用 bcp 实用工具导出由该视图定义的数据。如果可以使用 Insert 语句向视图中插入行,则还可以使用 bcp 实用工具或 BULK Insert 语句将数据从数据文件导入某些视图。有关向视图中复制数据的限制的详细信息,请参阅 Insert (Transact-SQL)。有关如何使用 bcp 实用工具和 BULK Insert 语句向视图复制数据和从视图复制数据的详细信息,请参阅从视图导出数据或将数据导入视图

跨服务器组合分区数据

Transact-SQL UNION 集合运算符可在视图内使用,将单独表的两个或多个查询的结果组合到单一的结果集中。这在用户看来是一个单独的表,称为分区视图。例如,如果一个表包含华盛顿的销售数据,另一个表包含加利福尼亚的销售数据,则可以对这两个表使用 UNION 创建一个视图。该视图代表这两个地区的销售数据。

使用分区视图时,请您首先创建几个相同的表,指定一个约束以确定可在各个表中添加的数据范围。然后,使用这些基表创建视图。查询视图时,SQL Server 将自动确定查询所影响的表并仅引用这些表。例如,如果一个查询指定只需要华盛顿州的销售数据,SQL Server 将只读取包含华盛顿销售数据的表,而不访问其他表。

分区试图可基于来自多个异类源(如远程服务器)的数据以创建数据库服务器的联合体。例如,若要将分别存储组织中不同区域数据的几台远程服务器上的数据组合起来,可以创建分布式查询,从每个数据源中检索数据,然后基于这些分布式查询创建视图。所有查询都只读取包含查询所请求数据的远程服务器上的表中的数据,而不访问由视图中的分布式查询所引用的其他服务器。

跨多个服务器对数据进行分区时,只访问一部分数据的查询可以较快地运行,因为只需扫描较少的数据。如果表位于不同服务器上,或者位于一台使用多个处理器的计算机上,则还可以并行扫描该查询所涉及的每个表。这可以提高查询性能。此外,维护任务(例如重新生成索引或备份表)可更快地执行。

通过使用分区视图,数据的外观象是一个单一表,并且能以单一表的方式进行查询,而无需手动引用正确的基础表。

注意:
本地分区视图或组合同一个服务器上表中的分区数据的视图包含在 Microsoft SQL Server 2005 中,只是为了提供向后兼容性。本地分区数据的首选方法是通过已分区表。有关详细信息,请参阅已分区表和已分区索引

如果满足下列任一条件,则分区视图可被更新:

  • 具有逻辑的视图定义支持 Insert、Update 和 Delete 语句的 INSTEAD OF 触发器。

[JQuery]JQuery的50个特色插件

mikel阅读(859)

原文:50+ Amazing Jquery Examples- Part1

JQuery是近段时间里比较流行的一个JavaScript框架,不断有使用者开发出新的 JQuery插件。下面收集了50个开发者最喜欢使用的jQuery插件。这仅仅是第一个系列,你先品尝,第二道大餐即将到来。
Sliding Panels -滑动门控制
1) Sliding Panels For jQuery -元素可以展开或关闭,创建出手风琴的滑动效果。

(2) jQuery Collapse -这个jQuery插件同样点击后滑动展开或关闭DIV层。
Menu - 菜单
3) LavaLamp

menu

(4) A Navigation Menu– 锚链接的无序列表嵌套, 可以添加2级菜单

menu

(5) SuckerFish Style

menu

Tabs – 选项卡
6) jQuery UI Tabs / Tabs 3 – 基于 jQuery 的一个Tab选项卡导航

(7) TabContainer Theme – 当用户在选项卡之间进行切换时,产生JQuery风格的淡出动效果。


Accordion- 手风琴效果
8 ) jQuery Accordion

Demo
accordion

(9) Simple JQuery Accordion menu

accordion
SlideShows - 幻灯片
10) jQZoom-让你在你的网页上很简单的实现图片的缩放功能。

rating

(11) Image/Photo Gallery Viewer– 一个图像/相片的画廊展示插件。可以让你对图片进行分组、并产生像Flash一样的多种浏览特效。

rating
Transition Effects – 过渡特效
12) InnerFade – 可以让网页中的任何元素产生淡化效果

(13) Easing Plugin-另外一个简单的过渡效果插件

(14) Highlight Fade

(15) jQuery Cycle Plugin– 拥有多种过渡效果的一个Gallery插件。

accordion

奇幻的jQuery
16) Riding carousels with jQuery – 这个jQuery插件可以生成一个水平或垂直的列表,并且允许你控制DIV层的滑动显示。

Demo :

Color Picker -拾色器
17) Farbtastic -这个 jQuery 插件可以让你通过JavaScript添加一个或多个拾色器widgets到一个页面中。

Demo :

(18) jQuery Color Picker
LightBox -灯箱效果
19) jQuery ThickBox – is a webpage user interface dialog widget written in JavaScript.

Demo :

(20) SimpleModal Demos – its goal is providing developers with a cross-browser overlay and container that will be populated with content provided to SimpleModal.

Demo :

(21) jQuery lightBox Plugin – simple, elegant, unobtrusive, no need extra markup and is used to overlay images on the current page through the power and flexibility of jQuery′s selector.

Demo :

(
iframe
22) JQuery iFrame Plugin


Form Validation -表单验证器
23) Validation – 有一套完整相当的形式验证规则。该插件还动态地创建ID和联系信息。

Demo :

(24) Ajax Form Validation – 在客户端使用jquery验证的一种形式,它可以验证用户名是否有效等。

Demo :

(25) jQuery AlphaNumeric -欢迎对对表单域中的某些字符进行限制


Form Elements - 表单事件

(26) jquery.Combobox – 从现在的选择元素中创建一个个性的HTML组合 Demo is here.

(27) jQuery Checkbox -样式化选择框,从而提高交互能力。

(28) File Style Plugin for jQuery -File Style插件让你可以使用图像做为文件浏览按钮,你还可以样式化文件名称区域。
Star Rating - 星形评级系统
rating

(29) Simple Star Rating System

30)Half-Star Rating Plugin
ToolTips -提示工具
31) Tooltip Plugin Examples – 一个花俏的提示应用。 可以对提示信息进行自定义位置, 设置阴影效果和添加更多内容等.你可以点击demo 演示.

(32) The jQuery Tooltip

tool tip
Tables Plugins -表格插件
33) Zebra Tables Demo -使用jQuery来创建出斑马线风格的数据表格,鼠标悬浮时能改变背景色。

Demo :

zebra tables

(34) Table Sorter Plugin – 把一个标准的HTML表格分解成Thead和Tbody标签构成的分类表格,不需要刷新。它能够成功地解析和整理多种类型的数据,包括联系资料。

table sorter

(35) AutoScroll for jQuery -可以生成网页表格的热点自动滚动效果

auto scroll

(36) Scrollable HTML table plugin– 用来转换表格为普通的滚动HTML。不需要额外的编码。

Demo :

Scrollable table
Draggable Droppables And Selectables 拖拽
37) Sortables – 一个简单强大的拖拽插件。

sort

(38) Draggables and droppables– 这是一个很好的演示。用来实现拖拽树形菜单项目的操作

drag drop
Style Switcher - 切换风络
39) Switch stylesheets with jQuery允许访客选择他们喜欢的网站样式,使用了Cookie记录,也就是同一个用户下次再访问时,除非他不切换,否则会保留他选择的样式。

Demo演示.
Rounded Corners 圆角效果
40) jQuery Corner Demo

rounded corners

(41) JQuery Curvy Corners– 这个插件可以让你生成光滑、无锯齿的圆角效果。

rounded corners
Must See jQuery Examples 应该了解的一些jQuery应用实例
42) jQuery Air – 一个非常非常特别的客户管理界面应用插件,太特别了,太太太特别了。

Demo :

(43) HeatColor

Demo :

(44) Simple jQuery Examples

(45) Date Picker -一个灵活个性的jQuery日历组件。

Demo :

(46) ScrollTo -这个jQuery插件可以让你实现当点击链接时中滚动到页面中的某一对象

(47) 3-Column Splitter Layout 一个3栏布局分配插件。

(48) Pager jQuery -一个小巧的 jQuery插件,用来增加分页的页码效果

(49) Select box manipulation

(50) Cookie Plugin for jQuery

51) JQuery BlockUI Plugin




[CSS]页面中的Pre标签换行问题

mikel阅读(1181)

本站文章中使用了 pre 格式输出 代码。 而浏览器默认是强制不换行输出 pre 里的内容。这样的话,代码一长就出现了撑到页面外部的样子。在之前我都是有意的在代码里强制换行… 累啊. 今天有意的google了下,找到了:

pre {
white-space: pre-wrap; /* css-3 */
white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
white-space: -pre-wrap; /* Opera 4-6 */
white-space: -o-pre-wrap; /* Opera 7 */
word-wrap: break-word; /* Internet Explorer 5.5+ */
}

经测试,除IE[当前使用6] 外, 其他可以…. 郁闷,然后增加 width:600px; 后,ok,.换行了,其实位置还是衍生出去了。样子是这样的: 代码是在里面了,但下面的叙述性的东西却出了去。在说,定义一个这个宽度也不是个好的方法,其他的不直接改这个css的方法基本没有了。

然后看上面css想到, 为什么定义其他的都用 white-space 而定义 IE 的不使用呢? 又不是IE 不支持。。于是加上就可以了[翻了google的前5页, 没找到一个改css解决的…汗]。

 pre {
white-space: pre-wrap; /* css-3 */
white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
white-space: -pre-wrap; /* Opera 4-6 */
white-space: -o-pre-wrap; /* Opera 7 */
word-wrap: break-word; /* Internet Explorer 5.5+ */
white-space : normal ;       /* Internet Explorer 5.5+ */
}

至于本站上使用的是把ie和其他的分开了,因为white-space 在最后也都作用于其他了….

pre {
white-space: pre-wrap;       /* css-3 */
white-space: -moz-pre-wrap;  /* Mozilla, since 1999 */
white-space: -pre-wrap;      /* Opera 4-6 */
white-space: -o-pre-wrap;    /* Opera 7 */
}
* html pre {
word-wrap: break-word;       /* Internet Explorer 5.5+ */
white-space : normal ;       /* Internet Explorer 5.5+ */
}

End. by Autoit.


Permanent URL: http://www.autoit.cn/index.php/content/view/96/2.html

[测试]web性能测试分析-工具篇

mikel阅读(1118)

用于Web性能分析的工具还有很多,以下只不过是我所略知的几种,如各位有使用未列出性能工具,请跟帖共享。以下软件都可容易下载到.我建议全部下载,根据自已的需求,选择最适合自己的一款,呵呵,这个工作比较累呀。

微软官方免费软件:

CLRProfiler

是一个可以用于分析.NET程序行为的工具。可用其分析垃圾回收器堆正在发生的事情,例如什么方法分配了什么类型的对象?另外,还提供了调用图(call graph)功能用于显示哪个方法调用了哪个方法

Microsoft Web Application Stress Tool

Microsoft Web Application Stress Tool 是由微软的网站测试人员所开发,专门用来进行实际网站压力测试的一套工具。透过这套功能强大的压力测试工具,您可以使用少量的Client端计算机仿真大 量用户上线对网站服务所可能造成的影响,在网站实际上线之前先对您所设计的网站进行如同真实环境下的测试,以找出系统潜在的问题,对系统进行进一步的调 整、设置工作。

Microsoft Application Center Test

Microsoft Application Center Test是vs.net2003企业版自带的一个测试工具.使用它可以收集性能信息.确定WEB应用程序的容量.也可以创建测试,模拟同时从WEB应用程 序请求网页的多个用户.这些模拟测试有助于确定应用程序的稳定性.速度和响应能力.

商业软件(其实试用30天已经足够用了):

dotTrace

是个很不错的分析工具(Profiling Tool),可以分析windows form和ASP.NET ,它能够快速分析、过滤、函数查找(快速定位function,并且导航)和查看源码.

试用版下载(http://www.red-gate.com/products/ants_profiler/index.htm)

ANTS Profiler

一个检测基于.Net Framework的任何语言开发出的应用程序的代码性能的工具。她可以通过记录每行代码花费的时间,来帮助你优化程序的执行,而且可以用很多种格式来探测应用程序中效率不好的区域。ANTS Profiler还可以分析应用程序的内存使用状况,她就是通记录每个对象分配的内存空间大小,来提供很多种报告样式给开着这察看哪个对象或者类占用了最多的内存,从而可以帮助你优化内存的使用。

试用版下载(http://www.red-gate.com/products/ants_profiler/index.htm)

AQTime

一款功能强大的Code Profiler工具,有很多种代码分析方式,一般主要是用它来做性能分析,目的是定位程序性能瓶颈,然后再有针对性地进行优化。函数追踪功能,能看清函数的调用,而且能定位到行级,确定系统性能的瓶颈。

试用版下载(http://www.automatedqa.com)

.NET Memory Profiler

是NET Memory Profiler是一款强大的.net 内存跟踪和优化工具。

DevPartner Studio Professional Edition

是一套功能非常强大全面性的软件开发除错工具,协助程序开发人员使用微软Visual Studio .NET与Visual Studio 6.0开发应用程序与WebService。 其功能包括扫描程序找出程序码潜在的问题,侦测执行阶段的错误,程序执行效能分析,分散式应用系统问题分析,与程序码测试涵盖度分析等。支持微软的 Visual Studio .NET、Native Windows或是两者混合使用的应用程序,加速应用程序的开发,提高应用系统的稳定性与执行效能。

LoadRunner

是否目前国内最多人用的压力测试工具,感觉与.net搭配不是很好。

[C#]URL中的中文编码

mikel阅读(1023)

问题来源:
    正在研究一个程序,输入一个关键字,能够把这个关键字发送到Google,yahoo等搜索引擎,进行搜索,然后打开结果网页。原理很简单。比如在 Google搜索China,搜索结果页面的URL就是“http://www.google.com/search?hl=zh-CN&q=China&lr=”。只要替换红颜色的内容,就可以按照不同的关键字搜索。
但是如果关键字是中文,就会出现问题。比如在google搜索“中国”,Url是“http://www.google.com/search?hl=zh-CN&newwindow=1&q=%E4%B8%AD%E5%9B%BD&lr=”。汉字“中国”被按照UTF-8的格式进行编码。
不仅汉字进行编码,一些特殊字符也会进行编码。比如搜索“C#”,URL是“http://www.google.com/search?hl=zh-CN&newwindow=1&q=C%23&lr=”。
一般来说,国外的网站都是按照UTF-8编码,而“百度”是按照“GB2312”进行编码的。比如搜索“中国”,URL是“http://www.baidu.com/s?wd=%D6%D0%B9%FA&cl=3”
我们对比一下:C#中国的编码

编码 结果 网站
UTF-8 C%23%E4%B8%AD%E5%9B%BD Google
GB2312 C%23%D6%D0%B9%FA BaiDu

总结:
UTF-8中,一个汉字对应三个字节,GB2312中一个汉字占用两个字节。
不论何种编码,字母数字都不编码,特殊符号编码后占用一个字节。
开始编程:

        public static string UrlEncode(string str, string encode)
        
{
            
int factor;
            
if (encode == "UTF-8")
                factor 
= 3;
            
if (encode == "GB2312")
                factor 
= 2;
            
//不需要编码的字符
            string okChar = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-*@";
            System.Text.Encoder encoder 
= System.Text.Encoding.GetEncoding(encode).GetEncoder();
            
char[] c1 = str.ToCharArray();
            System.Text.StringBuilder sb 
= new System.Text.StringBuilder();
            
//一个字符一个字符的编码
            for (int i = 0; i < c1.Length; i++)
            
{
                
//不需要编码
                if (okChar.IndexOf(c1[i]) > 1)
                    sb.Append(c1[i]);
                
else
                
{
                    
byte[] c2 = new byte[factor];
                    
int charUsed, byteUsed; bool completed;

                    encoder.Convert(c1, i, 
1, c2, 0, factor, trueout charUsed, out byteUsed, out completed);

                    
foreach (byte b in c2)
                    
{
                        
if (b != 0)
                            sb.AppendFormat(
"%{0:X}", b);
                    }

                }

            }

            
return sb.ToString().Trim();


        }

后来发现更简单的方法。

//按照UTF-8进行编码
string tempSearchString1 = System.Web.HttpUtility.UrlEncode("C#中国");
//按照GB2312进行编码
string tempSearchString2 = System.Web.HttpUtility.UrlEncode("C#中国",System.Text.Encoding.GetEncoding("GB2312"));

大家直接用第二种方法就行了。

[AS]基于豆瓣API的六度拓扑

mikel阅读(930)

6DTOP源代码版本1.0系列


欢迎各位朋友对六度拓扑的喜爱,六度拓扑应该算是我互联网实验中第一个称得上成熟的作品。
无论从构思,还是到创作的过程,直到最后的产品,我都是很满意的。
当然,最先要感谢还是豆瓣网能放出这个通过ID来查找朋友的API,没有这个API就没有这个作品。
那么大的一个网站,用自己服务器和带宽把API开放出来供大家使用,这种奉献的精神本身就很值得称道,所以,我觉得放出自己的源代码是很应该的事,而且,其中也一定会有很多的好处。
我在大学时代读过Linus Torvalds
自传<乐者为王>,我不敢奢谈自己的编程水平有多高,但我和Linus Torvalds一样,都对编程活动充满热情。对我而言,程序设计最大的乐趣就在于创作,这和歌手写歌,作家写文章从某种程度上是具有一致性,最终的作品是否能得到大家的认可,将是我最大的颀慰。
我喜欢李宗盛大哥的一句话:“一把琴,在它交在一个音乐人手中之前,基本上是个废物,它一定要落在一个做音乐的人手中,它才有了生命。”—–与所有喜欢创作的朋友共勉。
——————————————————————-
好,书归正传,让我们说说代码吧:
1.首先要说的是关于程序编译环境,程序是用flash cs3编译的,虽然里面有一此看上去和flex有关的文件,但那只是我用flex作为编辑器所产生的"副产品",我采用开发方式是flash作为编译器和界面设计工具,而flex作为代码编辑器。
flash cs3 下载地址
至于flash所采用的开发语言——ActionScript 3,如果你学过像JAVA,C++这样的OOP语言,从语法能很轻松的理解。
2.程序之核心
2.1
程序最重要的一个部分就是"轨道",参UIEntity.Orbit

轨道图示
从图中,可以看出,结点是被一个吸引到轨道上去的。
而轨道的吸引是分阶段,第一阶是RANDOM_ATTRACT,第二阶段是ARRANGE。
RANDOM_ATTRACT:由于在二度及以上的朋友中,无法在搜索完成某度的所有朋友前,获知其朋友的数目,因此,为了让头像可以尽可能的均匀排列,需要根据当前已搜索的某度朋友的数目来进行,这个阶段称为RANDOM_ATTRACT。
ARRANGE:这个阶段就很清楚了,某个朋友的某度朋友全部完成时,让其朋友尽可能的均匀排列。
轨道的实现用的是DFA(有限自动机),其实我这里的实现是很简单的,就是在一个可以被反复执行的函数,如foo中,加swith(status)这样的语句,GOT IT?
DFA是我在交互应用中非常喜欢用的东西,我对它喜欢的不得了,他真是个既简单,又有效的思想。
如果我说程序的核心就这点的话,肯定有人要扔蕃茄了,但事实就是这样,这个就是程序之核心,当然,实现这个核心的某些细节还是很值得讨论下的。
2.2Orbit吸引之实现
Orbit自己只负责完成吸引的动作,但由谁负责把结点push进某个orbit呢?这就需要由另一个自动机来做,参看DouBanFriendTopology类(主类)中的
enterFrameFun(evt:Event):void函数的实现
它的基本思想是这样的,将当前中心点的一度用户装入一个队列中,
然后,每隔50ms左右(出于性能考虑),从队列(参AS3STL.EQueue)Q的头部取出一个用户F->
     查看用户F的朋友是否已全部获取(由于豆瓣朋友的XML一次只能请求50个,所以当朋友大于50时,要多次请求)。
     YES
全部获取 : 把用户F用队列Q里取出,查看它的所有朋友结点。
         IF  
朋友结点i未被使用
              加入队列Q的尾部      
         ELSE
直接丢弃此结点,这里为了避免重复结点,
              如a-b是好友,b-c是好友,而c-a又是好友

        
     NO
未全部获取: 等待
这是一个很简单但很有效的算法,不是吗?
因为这里,只要不停止抓取,用户的朋友,朋友的朋友…是会一直获取(抓取的过程参
DouBanFriendTopology类中的ClawMainFun(event:TimerEvent):void)下去的,也就是说,队列是无限延伸(除非把N度朋友全抓完或到某度时所有人都没有朋友了),对于这样一种动态的数据的情况,本来是很麻烦的,但这里用一个"查看用户F的朋友是否已全部获取"就优雅的处理了这一情况,个人对此颇为满意。
3OK,关键的部分就先介绍到这里了,先讲讲程序的组织:
Douban_Fri_Topology.fla 程序主文件,编辑它即可观看6度拓扑。
DouBanFriendTopology.as 程序的主类。
OriginalGraph.fla       程序的原型图所在文件,用于先期设计。
about.swf              点 击About后播放的flash文件,里面用到了我最喜欢的美                       国选秀结目<学徒>的背景音 乐。(第一帧被设为暂停了,要通                        过程序控制播放)
——————————————————————

AS3STL                 
自写的AS3 STL包,目前仅有一个队列(以前有一个较全的
AS2STL,有stack,tree,graph啥的,过一阵改写)。
               
ComuEntity             
通讯实体类,用来请求XML,并返回相应结果,        
Fetch_Friend.as是用来获取朋友数据的。
而Fetch_People.as则是在搜索时用来获取个人信息(ID)的,主要用在如http://www.6dtop.com/search.asp?id=ahbei上。
EventCenter
CEventCenter, 这是一种形之有效的自写消息的机制,当你从一个“深处”,比方说obj1.obj2.obj3.xxx发出一个消息给obj100,通过这样一种直接管理 -派发的机制,有效的解决了这个问题,无论语言是否带什么dispatch之类的自定义消息机制,都可以用这种基于函数实现的消息来做。
CGData
用来存放一些全局数据,UserList是一个全局的异质(就是不会有重复的)用户列表。
Model
用来定义一些仅和数据相关的模型,如这里的UserModel.
UIEffect
效果包,DragEffectVM是我非常颀常的一个自写鼠标拖动管理类,他带来了非常高的便捷性和灵活性。
UIEntity
UI 实体包,其中的Orbit(轨道)和UserNode(用户结点)最为重要,而ToolBar中包括了ScaleToolBar(左侧形变工 具),Upline(上部工具),ButtomLine(下部工具),这里用到了在flash制作的一些元件,在FLEX里由于无法识别,会报错(由于没 有编译成.swc),不用理会,因为这里是用flash进行编译的。
Utils
实用类包,ArrayUtil,数组辅助方法。
WebService
WebService包,SWebService,包含了请求的地址等。
——————————————————————
about_swf文件夹,包含了about flash的源文件。
由于about.swf第一帧被设为了暂停,所以,可以使用loader.swf
——————————————————————
说了大半天,终于来点实惠的了,6DTOP 源码1.0版本,跟大家分享了
http://www.6dtop.com/open/v1.0/6dtop.source.1.0.rar

[Adobe]Adobe发布的Adobe CS4下载

mikel阅读(756)

感谢abc的投递
新闻来源:原创
几天前Adobe 官方宣布CS4推出,正式版会在10月份发售,在国外网站找了半天,终于找到Flash CS4的试用版,BT了半天,而非正式发售版。
好东西当然与大家一起分享,在这里笔者就为大家评测部分Flash CS4的功能及界面,更多东西自行“哇”。

一、安装画廊
在网上下载后文件是Adobe Flash CS4 Install Americas.exe,点击选择解压,解压完成,安装开始,以下是截图;






开始菜单

桌面右键

二、功能
2.1 – 主界面

1、CS4的菜单栏进行了界面优化,你会发现更方便的使用;
2、快速更换布局,默认为Essentials,共分为6种布局,方便不同的用户群;
3、把常用工具和属性及图层库集合在一起,更能提升效率;
4、动画的关键帧放在最下方,你是否会发现在下方比上方好?
2.2 – 利用Flash Cs4 AIR 创建跨平台应用程序
细心的朋友,在上面看安装时的画廊就知道,组件里多了Adobe AIR,在“文件“里我们可以看到多了一项AIR Settings,有了发布AIR程序,当然我们可以轻松的创建AIR程序。
2.3 – 分享我的屏幕
大家还记得原来微软发布过Share桌面软件,这个功能跟微软的相似,点击“文件” –“Share my screen”,然后登录,如图。

登录完成后,自动启动Adobe Connectnow程序,把上面的地址发送给对方,也可利用Email进行发送;

多功能协作

2.5 – 崩溃的后果
这年代崩溃也不需要标题,直接意外事故更好,流行。

三、Adobe Media Encode Cs4
利用Media Encoder转换吧,记得原来需要单独下载,现在集成到一起来啦。

四、更多截图画廊
4.1 – Adobe Extension Manager

4.2 – Adobe Desktop

4.3 – Adobe Device Central CS4

4.4 –Adobe ExtendScript Toolkit CS4
 
4.5 – Adobe Drive CS4

结论
试用了Flash CS4过后,感觉变化最大就是优化了界面,不过遗憾的是Flash CS4测试版中的语言很乱,如 Adobe Extension Manager CS4和Adobe Drive CS4是中文的,Flash CS4 却是英文的,安装也是全中文,不过遗憾的是只能选择4种语言,里面并没有包含中文,一直在想。Adobe应该中文集成到默认语言,这样更多朋友会体验新产 品。

Flash CS4最值得让我们选择他的几点好处:

1.CS4带来了最新的AIR程序创建,也许以后你创建安装程序你会选择AIR(自己原来就有这种想法,AIR的安装流程做得非常的漂亮);
2.优化后的界面看起来更漂亮,更适合多显示器使用,默认布局对屏幕大的用户提供了良好的视觉等;
当然更多功能还需大家亲自体验,更多新鲜功能尽在CS4中,一起期待吧。真想ZzZzZz/..
Flash Cs4测试版下载:QQ中转站   (提取码 57f33f01)
Flash Cs4破解文件:QQ中转站  (提取码 e88b49ef)

[C#]泛型中的强制类型转换

mikel阅读(1485)

泛型类型中的变化(C# 编程指南)

更新:2007 年 11 月

C# 中添加泛型的一个主要好处是能够使用 System.Collections.Generic 命名空间中的类型轻松地创建强类型集合。例如,您可以创建一个类型为 List<int> 的变量,编译器将检查对该变量的所有访问,确保只将 List<int> 添加到该集合中。与 C# 1.0 版中的非类型化集合相比,这是可用性方面的一个很大改进。

遗憾的是强类型集合有自身的缺陷。例如,假设您有一个强类型 List<object>,您想将 List<int> 中的所有元素追加到 List<object> 中。您可能希望能够如下面的示例一样编写代码:

List<int> ints = new List<int>();
ints.Add(1);
ints.Add(10);
ints.Add(42);
List<object> objects = new List<object>();
// doesnt compile ints is not a IEnumerable<object>
//objects.AddRange(ints); 

在这种情况下,您希望能够将 List<int>(它同时也是 IEnumerable<int>)作为 IEnumerable<object> 处理。这样做看起来似乎很合理,因为 int 可以转换为对象。这与能够将 string[] 当作 object[](现在您就可以这样做)非常相似。如果您正面临这种情况,那么您需要一种称为泛型变化的功能,它将泛型类型的一种实例化(在本例中为 IEnumerable<int>)当成该类型的另一种实例化(在本例中为 IEnumerable<object>)。

由于 C# 不支持泛型类型的变化,所以当遇到这种情况时,您需要尝试几种可能的方法来解决此问题。对于最简单的情况,例如上例中的单个方法 AddRange,您可以声明一个简单的帮助器方法来为您执行转换。例如,您可以编写如下方法:

// Simple workaround for single method
// Variance in one direction only
public static void Add<S, D>(List<S> source, List<D> destination)
where S : D
{
foreach (S sourceElement in source)
{
destination.Add(sourceElement);
}
}

它使您能够完成以下操作:

// does compile
VarianceWorkaround.Add<int, object>(ints, objects);

此示例演示了一种简单的变化解决方法的一些特征。帮助器方法带两个类型参数,分别对应于源和目标,源类型参数 S 有一个约束,即目标类型参数 D。这意味着读取的 List<> 所包含的元素必须可以转换为插入的 List<> 类型的元素。这使编译器可以强制 int 可转换为对象。将类型参数约束为从另一类型参数派生被称为裸类型参数约束。

定 义一个方法来解决变化问题不算是一种过于拙劣的方法。遗憾的是变化问题很快就会变得非常复杂。下一级别的复杂性产生在当您想要将一个实例化的接口当作另一 个实例化的接口时。例如,您有一个 IEnumerable<int>,您想将它传递给一个只以 IEnumerable<object> 为参数的方法。同样,这样做也是有一定意义的,因为您可以将 IEnumerable<object> 看作对象的序列,将 IEnumerable<int> 看作 ints 的序列。由于 ints 是对象,因此 ints 的序列应当可以被当作对象序列。例如:

static void PrintObjects(IEnumerable<object> objects)
{
foreach (object o in objects)
{
Console.WriteLine(o);
}
}

您可能希望能够如下面的示例一样调用:

// would like to do this, but cant ...
// ... ints is not an IEnumerable<object>
//PrintObjects(ints);

接口 case 的解决方法是:创建为接口的每个成员执行转换的包装对象。这可能类似于如下示例:

// Workaround for interface
// Variance in one direction only so type expressinos are natural
public static IEnumerable<D> Convert<S, D>(IEnumerable<S> source)
where S : D
{
return new EnumerableWrapper<S, D>(source);
}
private class EnumerableWrapper<S, D> : IEnumerable<D>
where S : D
{

它使您能够完成以下操作:

PrintObjects(VarianceWorkaround.Convert<int, object>(ints));

同样,请注意包装类和帮助器方法的裸类型参数约束。此 系统已经变得相当复杂,但是包装类中的代码非常简单;它只委托给所包装接口的成员,除了简单的类型转换外,不执行其他任何操作。为什么不让编译器允许从 IEnumerable<int> 直接转换为 IEnumerable<object> 呢?

尽管在查看集合的 只读视图的情况下,变化是类型安全的,然而在同时涉及读写操作的情况下,变化不是类型安全的。例如,不能用此自动方法处理 IList<> 接口。您仍然可以编写一个帮助器,用类型安全的方式包装 IList<> 上的所有读操作,但是写操作的包装就不能如此轻松了。

下面是处理 IList<(Of <(T>)>) 接口的变化的包装的一部分,它显示在读和写两个方面的变化所引发的问题:

private class ListWrapper<S, D> : CollectionWrapper<S, D>, IList<D>
where S : D
{
public ListWrapper(IList<S> source) : base(source)
{
this.source = source;
}
public int IndexOf(D item)
{
if (item is S)
{
return this.source.IndexOf((S) item);
}
else
{
return -1;
}
}
// variance the wrong way ...
// ... can throw exceptions at runtime
public void Insert(int index, D item)
{
if (item is S)
{
this.source.Insert(index, (S)item);
}
else
{
throw new Exception("Invalid type exception");
}
}

包装中的 Insert 方法有一个问题。它将 D 当作参数,但是它必须将 D 插入到 IList<S> 中。由于 D 是 S 的基类型,不是所有的 D 都是 S,因此 Insert 操作可能会失败。此示例与数组的变化有相似之处。当将对象插入 object[] 时,将执行动态类型检查,因为 object[] 在运行时可能实际为 string[]。例如:

object[] objects = new string[10];
// no problem, adding a string to a string[]
objects[0] = "hello";
// runtime exception, adding an object to a string[]
objects[1] = new object();

在 IList<> 示例中,当实际类型在运行时与需要的类型不匹配时,可以仅仅引发 Insert 方法的包装。所以,您同样可以想象得到编译器将为程序员自动生成此包装。然而,有时候并不应该执行此策略。IndexOf 方法在集合中搜索所提供的项,如果找到该项,则返回该项在集合中的索引。然而,如果没有找到该项,IndexOf 方法将仅仅返回 -1,而并不引发。这种类型的包装不能由自动生成的包装提供。

到目前为止,我们描述了泛型变化问题的两种最简单的解决方法。然而,变化问题 可能变得要多复杂就有多复杂。例如,当您将 List<IEnumerable<int>>当作 List<IEnumerable<object>>,或将 List<IEnumerable<IEnumerable<int>>> 当作 List<IEnumerable<IEnumerable<object>>> 时。

当生成这些包 装以解决代码中的变化问题时,可能给代码带来巨大的系统开销。同时,它还会带来引用标识问题,因为每个包装的标识都与原始集合的标识不一样,从而会导致不 易察觉的 Bug。当使用泛型时,应选择类型实例化,以减少紧密关联的组件之间的不匹配问题。这可能要求在设计代码时做出一些妥协。与往常一样,设计程序时必须权衡 相互冲突的要求,在设计过程中应当考虑语言中类型系统具有的约束。

有的类型系统将泛型变化作为语言的首要任务。Eiffel 是其中一个主要示例。然而,将泛型变化作为类型系统的首要任务会明显增加 C# 的类型系统的复杂性,即使在不涉及变化的相对简单方案中也是如此。因此,C# 的设计人员觉得不包括变化才是 C# 的适当选择。

下面是上述示例的完整源代码。

using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
static class VarianceWorkaround
{
// Simple workaround for single method
// Variance in one direction only
public static void Add<S, D>(List<S> source, List<D> destination)
where S : D
{
foreach (S sourceElement in source)
{
destination.Add(sourceElement);
}
}
// Workaround for interface
// Variance in one direction only so type expressinos are natural
public static IEnumerable<D> Convert<S, D>(IEnumerable<S> source)
where S : D
{
return new EnumerableWrapper<S, D>(source);
}
private class EnumerableWrapper<S, D> : IEnumerable<D>
where S : D
{
public EnumerableWrapper(IEnumerable<S> source)
{
this.source = source;
}
public IEnumerator<D> GetEnumerator()
{
return new EnumeratorWrapper(this.source.GetEnumerator());
}
IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
private class EnumeratorWrapper : IEnumerator<D>
{
public EnumeratorWrapper(IEnumerator<S> source)
{
this.source = source;
}
private IEnumerator<S> source;
public D Current
{
get { return this.source.Current; }
}
public void Dispose()
{
this.source.Dispose();
}
object IEnumerator.Current
{
get { return this.source.Current; }
}
public bool MoveNext()
{
return this.source.MoveNext();
}
public void Reset()
{
this.source.Reset();
}
}
private IEnumerable<S> source;
}
// Workaround for interface
// Variance in both directions, causes issues
// similar to existing array variance
public static ICollection<D> Convert<S, D>(ICollection<S> source)
where S : D
{
return new CollectionWrapper<S, D>(source);
}
private class CollectionWrapper<S, D>
: EnumerableWrapper<S, D>, ICollection<D>
where S : D
{
public CollectionWrapper(ICollection<S> source)
: base(source)
{
}
// variance going the wrong way ... 
// ... can yield exceptions at runtime
public void Add(D item)
{
if (item is S)
{
this.source.Add((S)item);
}
else
{
throw new Exception(@"Type mismatch exception, due to type hole introduced by variance.");
}
}
public void Clear()
{
this.source.Clear();
}
// variance going the wrong way ... 
// ... but the semantics of the method yields reasonable semantics
public bool Contains(D item)
{
if (item is S)
{
return this.source.Contains((S)item);
}
else
{
return false;
}
}
// variance going the right way ... 
public void CopyTo(D[] array, int arrayIndex)
{
foreach (S src in this.source)
{
array[arrayIndex++] = src;
}
}
public int Count
{
get { return this.source.Count; }
}
public bool IsReadOnly
{
get { return this.source.IsReadOnly; }
}
// variance going the wrong way ... 
// ... but the semantics of the method yields reasonable  semantics
public bool Remove(D item)
{
if (item is S)
{
return this.source.Remove((S)item);
}
else
{
return false;
}
}
private ICollection<S> source;
}
// Workaround for interface
// Variance in both directions, causes issues similar to existing array variance
public static IList<D> Convert<S, D>(IList<S> source)
where S : D
{
return new ListWrapper<S, D>(source);
}
private class ListWrapper<S, D> : CollectionWrapper<S, D>, IList<D>
where S : D
{
public ListWrapper(IList<S> source) : base(source)
{
this.source = source;
}
public int IndexOf(D item)
{
if (item is S)
{
return this.source.IndexOf((S) item);
}
else
{
return -1;
}
}
// variance the wrong way ...
// ... can throw exceptions at runtime
public void Insert(int index, D item)
{
if (item is S)
{
this.source.Insert(index, (S)item);
}
else
{
throw new Exception("Invalid type exception");
}
}
public void RemoveAt(int index)
{
this.source.RemoveAt(index);
}
public D this[int index]
{
get
{
return this.source[index];
}
set
{
if (value is S)
this.source[index] = (S)value;
else
throw new Exception("Invalid type exception.");
}
}
private IList<S> source;
}
}
namespace GenericVariance
{
class Program
{
static void PrintObjects(IEnumerable<object> objects)
{
foreach (object o in objects)
{
Console.WriteLine(o);
}
}
static void AddToObjects(IList<object> objects)
{
// this will fail if the collection provided is a wrapped collection 
objects.Add(new object());
}
static void Main(string[] args)
{
List<int> ints = new List<int>();
ints.Add(1);
ints.Add(10);
ints.Add(42);
List<object> objects = new List<object>();
// doesnt compile ints is not a IEnumerable<object>
//objects.AddRange(ints); 
// does compile
VarianceWorkaround.Add<int, object>(ints, objects);
// would like to do this, but cant ...
// ... ints is not an IEnumerable<object>
//PrintObjects(ints);
PrintObjects(VarianceWorkaround.Convert<int, object>(ints));
AddToObjects(objects); // this works fine
AddToObjects(VarianceWorkaround.Convert<int, object>(ints));
}
static void ArrayExample()
{
object[] objects = new string[10];
// no problem, adding a string to a string[]
objects[0] = "hello";
// runtime exception, adding an object to a string[]
objects[1] = new object();
}
}
}

[C#]泛型与强制类型转换

mikel阅读(1183)

4. 泛型和强制类型转换

  4.1 C#编译器只允许将泛型参数隐式强制转换到Object或约束指定的类型

          interface ISomeInterface

      { ……}

     class BaseClass

      {……}

      class MyClass<T> where :BaseClass ,ISomeInterface

      {

        void SomeMethod(T t)

        {

            //类型安全的,编译时检查

            ISomeInterface obj1=t;

            BaseClass obj2=t;

            object obj3=t

        }

       }

   4.2 编译器允许你将泛型参数显示强制转换到其他任何接口,但不能将其转换到类

           interface ISomeInterface

       { ……}

     class SomeClass

       {……}

       class MyClass<T>

       { 软件开发网 www.mscto.com

         void SomeMethod(T t)

         {

            ISomeInterface obj1=(ISomeInterface)t;  //complies

            SomeClass obj2=(SomeClass)t;            //Does not complies

         }

        }

           但是,使用临时的 Object 变量,将泛型参数强制转换到其他任何类型

            class SomeClass

        {……}

       class MyClass2<T>

        {

            void SomeMethod(T t)

           {

软件开发网 www.mscto.com

               object temp = t;

                SomeClass obj = (SomeClass)temp;

            }

          }

     4.2 不用说强制转换时危险的,因为如果为取代泛型参数而使用的类型参数不是派生自你要显示强制转换到的类型,则可能引发异常。 软件开发网 www.mscto.com

        解决强制类型转换的方法:使用isas运算符

        public class MyClass3<T>

        {

             public void SomeMethod(T t)

             { 软件开发网 www.mscto.com

                   //如果泛型参数的类型是所查询的类型,则is运算符返回true

                   if (t is int) { }

                   if (t is LinkedList<int, string>) { }

软件开发网 www.mscto.com

                   string str = t as string; 软件开发网 www.mscto.com

                   if (str != null) { }

                   LinkedList<int, string> list = t as LinkedList<int, string>;

                   if (list != null) { }

              } 软件开发网 www.mscto.com

         }