[翻译]List为什么实现了那么多接口?
[翻译]List
原文地址: http://blogs.msdn.com/b/ericlippert/archive/2011/04/04/so-many-interfaces.aspx
原作者: Eric Lippert
Eric Lippert是微软员工,C#编译器的主要开发人员之一。
今天,我在 StackOverflow
上回答了一个问题。按照以往的习惯,我把它以对话体的形式整理成一篇博客。
MSDN的文档中说List
“可选参数”趣事探轶
上一篇博文
中提到了“可选参数”这个C# 4.0中新增的语言特性,但是写过之后还是不满足,心里还是有一些疑问没有得到解释。于是又做了一些探索,过程中竟然发现这么一个小小
的语言特性背后隐藏着的有趣问题还真不少。这次就把探索过程中的发现和疑问记录下来。
“可选参数”的实现
Cnblogs上有一篇 蒋金楠的文章
中提到一句:“缺省参数最终体现为两个特殊的自定义特性OptionalAttribute和DefaultParameterValueAttribute
”。为了验证这个说法的正确性,我自己做了一些试验。
要研究语言特性的实现原理最好的方法莫过于反编译出IL代码来一探究竟了。所以,那就顺着这条线索走吧。
首先用C#代码写一个很简单的测试方法:
public void TestMethod(string str = "A")
{
}
C#中的语言特性都是从何而来?
前几天推荐一个同事用“可选参数”,推荐完了我还画蛇添足的说这是.Net 4中的新特性。但是事后才发现这个新特性是C# 4.0的语言特性,与.Net
4无关。其实也不只这一次,我平时也经常把语言、框架、运行时,有时甚至还有开发工具混为一谈。于是今天就总结一下C#中我感兴趣的几个语言特性是从何而来的。
** 1.可选参数 **
可选参数是C# 4.0中的新特性,其作用在于在调用者不提供参数值时给参数一个默认值,用起来是这样的:
static void Main(string[] args)
{
TestMethod();
TestMethod(10);
Console.ReadLine();
}
public static void TestMethod(int parameter = 5)
{
Console.WriteLine(parameter);
}
以上的代码在第一次调用TestMethod时输出5,第二次输出10,也就是在没有给TestMethod提供参数值时,会自动以5作为参数值。
该特性的实现依赖于OptionalAttribute和DefaultParameterValueAttribute这两个attribute,也就是说Test
Method这个方法完全可以声明为这样:
送给所有需要学英语的朋友—Words Via Subtitle
从名字就可以看出来,Words Via Subtitle是用来通过字幕学单词的辅助工具。它通过解析美剧或者电影的字幕文件把其中的生词取出,用网络上提供的开放
API或者本地词库解释生词。另外,程序还可以提供单词读音(机器发音),可以播放一个单词在剧中出现的语境,可以把所有生词串起来像幻灯片一样连续播放,也就是说显
示一个单词及其解释,然后用机器发音读该单词,然后播放该单词在剧中出现的句子,然后切换到下一个生词再重复这一过程。
这个程序去年就写过一个雏形,最近断断续续的重写了。这次主要的改进是将字幕的分析和单词的解释从主程序中抽出来做成插件,也就是说主程序部署到一台机器之后如果想要
增加对一种字幕格式的支持就只需要写一个插件拷到部署的机器上去就ok了,无需把整个程序重新编译、重新部署。同样,如果想要增加一种单词解释器也可以通过添加一个插
件完成,比如说现在只有一个很小的本地词库和一个网络释义,之后有人想给这个程序增加一个Google词典的解释器就可以写一个插件来完成。这次重写用了WPF、ME
F,以及Ribbon Controls等最近接触的新东西,不过在这儿暂时不介绍程序是怎么写,也不说字幕解析插件和解释提供器插件如何编写,先简单介绍一下各功能
的使用吧。对代码感兴趣的朋友可以去CodePlex上去搜索WVS(Words Via Subtitle的简写),我把这个程序作为一个开源项目上传到那儿了
,用的MS-PL协议,完全开源哈。
下面就开始说一下大概怎么用这个程序吧。
运行程序,用左上角的Open按钮(](/images/attachment/201010/24/0_12879076954nrG.gif)
)打开一个字幕文件(现在可以支持srt和ass格式的,当然以后可以通过插件来添加对更多种类的字幕的支持)。
](/images/attachment/201010/24/0_1287907700gCeG.gif)
上图中右下角可选的文件格式会随着插件的增多而增多。
百度游戏 七彩鱼 自动喂鱼器
前几天有朋友推荐我玩百度的网页游戏“七彩鱼”,玩儿了几天感觉还行,就是老得盯着喂鱼太麻烦。十一闲着没啥事儿干,于是就自己写了个喂鱼器。
具体使用方法写起来有点麻烦,我录了一段视频传到了56上,地址在下面:
http://www.56.com/u84/v_NTUyNzE0NjU.html
喂鱼器程序的下载地址:
http://download.csdn.net/source/2732931
如果您用的是Vista或者Win7,本程序可以直接运行。但是如果是XP用户而且从没安装过.Net Framework的话那需要装一下.Net
Framework(2.0或以上版本)。
当Generic.xaml遇上BitmapImage:发现一个疑似WPF Bug而又不似Bug的问题
发现这个有点像 Bug 又不太像 Bug 的东西的过程是这样的:
我继承自 ContentControl 写了一个 MyContentControl ,在其中定义了一个叫做 IconProperty
的依赖属性及其对应的 CLR 属性并且在其静态构造中调用了 DefaultStyleKeyProperty.OverrideMetadata
方法,代码很少,看起来是这个样子的:
1 | class MyContentControl: ContentControl { |
其中的 Icon 属性声明类型为 ImageSource ,目的简单明了,当然就是给这个控件加个图标了。
然后再给这个自定义控件定义一个放在 Generic.xaml 里的 Template ,一样很简单,只是用一个 StackPanel 把它的
Icon 和 Content 包起来,代码是这样的:
1 | <Style TargetType="{x:Type local:MyContentControl}"> |
WPF中ItemContainerStyle不适用的一种情况
WPF中的ItemsControl定义了 ItemContainerStyle 这一属性,顾名思义,该属性用来给
ItemsControl中包含的每一个Item的容器定义样式 。
比如在ListBox中这个容器就是ListBoxItem,在TabControl中这个容器就是TabItem。
下面是 ItemContainerStyle 的一种简单应用:
XAML:
1 | <Window> |
在这段 XAML中 定义了一个ListBox,在其ItemTemplate中有一个TextBlock绑定到数据实体的Text属性上。在其
ItemContainerStyle 中将其每个
Item的IsSelected属性绑定到数据实体的IsSelected上。其数据实体的生成在下面的代码中:
在.NET 4中调用GDAL库时遇到的问题及解决方法
最近需要在 .NET 4 的环境中调用 GDAL 库。 GDAL 本身是一套非托管类库,不过还好提供了托管的 Wrapper 。
这些托管的程序集被包含在了 FWTools 的安装包中, FWTools 中带的版本依赖于 gdal_fw.dll, gdal_fw.dll
是 GDAL 核心类库的修改版,而它依赖的其他非托管程序集太多了,加起来有 18M 左右。所以还是自己下载代码编译的好。
这篇文章
介绍了 1.4 版本的编译方法,该方法同样适用于现在的 1.7 版本。
编译好之后引用、调用、 Debug 都没问题,一切正常,但是如果用 Release 编译并在 VS 之外运行的话则会报出
AccessViolationException ,异常信息提示说访问了受保护的内存。我的第一反应就是托管的 Wrapper 中用 P/Invoke
调用了非托管程序集,而非托管程序集导致了这个问题。但是这个猜测并不能解释为什么只有在 .NET 4+Release+IDE
外运行的情况下才会出错的现象。
猜来猜去,找来找去找到了问题的所在:
GDAL 的托管 Wrapper 中有一个叫做 SWIGStringHelper
的类型,该类型的静态构造方法中执行了一些比较重要的初始化操作。另外一个叫做 OsrPINVOKE 的类中声明了一个 SWIGStringHelper
类型的私有静态字段,并在声明时就初始化了该字段,而且 OsrPINVOKE 中没有显式声明的静态构造。
MEF编程指南(前两节)
MEF编程指南(前两节)
在应用程序中使用MEF
在应用程序中使用MEF需要创建一个CompositionContainer的实例,向其中添加可组合的部件,将宿主应用包含进去然后组合。
以下是使用MEF需要用到的步骤:
1、 创建一个宿主类。在接下来的示例中,我们将会使用一个控制台应用,所以宿主也就是Program类了。
2、 引用System.ComponentModel.Composition程序集
.NET 4.0 FAQ 第一部分—DLR
.NET 4.0 FAQ 第一部分—DLR
简介
本篇文章中我们将讨论.NET FrameWork 4.0提供了哪些新特性。然后再探讨DLR特性 中的动态对象和Expando对象。我们也将会创建一个Exp
ando对象来看我们可以从中获得哪些益处。很多的开发人员误以为动态对象是用来替代反射和object类型的,我们也将会纠正这种错误的概念。
.NET 4.0中有哪些重要的新特性?
与其去浏览.NET 4.0冗长的新特性列表,我们还是专注于我们认为最重要的三项新特性上吧。
• WF和WCF 4.0:这是.NET
用AvalonDock制作WPF多标签浏览器(三)
昨天遇到了一个 Bug ,如果在浏览器中打开多个标签,并把其中一个标签拖拽到主窗口的一侧来划分出独立的一个区域,然后在新区域中通过点击加号键添加的新标签内不会被添加上 WebBrowser 。
说得好绕嘴啊,截张图吧:
而且没有加上 WebBrowser 的标签的标题是 new content (我们在 AvalonDock 中给新标签的默认标题)而不是 New Tab (客户代码中重新赋的值)。
OK ,问题明了了,是不是新添加的标签的 Got_Focus 没能够挂到客户代码中的方法上去呢?
的确是这样,当我们把一个标签( DocumentContent )拖拽到一侧从而划分出一个新区域的时候, AvalonDock 会创建一个新的 DocumentPane 来代表这个新区域。
使用AvalonDock制作WPF多标签浏览器(二)
闲话少叙,书接上文。
现在我们已经通过 ReStyle 给 DocumentPane 加上了一个加号的按钮,并且可以通过点击该按钮给 DocumentPane 的
Items 添加一个 DocumentContent 了。
不过每个新添加进来的 DocumentContent 内部都是空的,而我们需要的是每个新标签中都有一个 WebBrowser
,要实现这一点很简单,只要给 DocumentContent 的 Content ( DocumentContent 是
ContentControl 的子类)属性赋值为一个 WebBrowser 的实例就 OK 了。
但是这不应该是 AvalonDock 的默认行为,所以我们要把这部分写到客户端 – 也就是引用 AvalonDock.dll
文件或者直接引用 AvalonDock 工程的 Solution 中去。
如何可以在客户端得知有一个新的 DocumentContent 被添加进 DocumentPane 中去了呢?自然是用事件了。
首先来写一个自定义的 EventArgs 吧:
使用AvalonDock制作WPF多标签浏览器(一)
AvalonDock 是 CodePlex 上的一个开源项目,利用它可以很容易的做出类似于 VS 的 UI 效果。
下图是 AvalonDock 源码中自带的一个 Demo :
我们可以用这款第三方控件为基础来制作多标签浏览器。
下面是最终效果图:
甚至可以把其中一个标签拖出主窗体成为一个独立的窗口:
Words Via Subtitle改进:视频播放例句、加快生成WPS文档的速度
Words Via Subtitle 改进:视频播放例句、加快生成 WPS 文档的速度
关于 Words Via Subtitle 的介绍:
1
http://blog.csdn.net/cuipengfei1/archive/2009/09/03/4516588.aspx
2
http://blog.csdn.net/cuipengfei1/archive/2009/09/10/4539180.aspx
最近给这个小程序添加了视频播放例句的功能,使用方法如下:
载入字幕文件并指定了与之对应的视频文件之后,选中某个感觉生疏的单词,然后点击播放例句按钮,该单词所在句子就会以视频的方式开始播放,播完该句子视频暂停。其实这
个功能写起来也挺简单的,就是在字幕中找到一个单词所在句子对应的时间信息,然后依照该时间段播放视频。
Words Via Subtitle的两点改进
上周写了一个
通过英文剧集、电影学单词的小工具
,这几天又做了一点小的改进。主要是下面这两点:
- 显示单词解释的同时显示其在剧中出现的语境,关键单词红色显示。效果如下:
- 导出文档。可以把列表中的单词,其简明解释和在剧中出现的语境保存到文档中。关键词开头绿色显示,例句中红色显示。效果如下:
为什么要写这个功能呢?因为九月中下旬有很多美剧要回归,包括 TBBT , Lie to me , Heroes , Fringe 。到时候每
一集出来之后可以用这个程序迅速的把一集中出现的生词,其音标及解释还有语境总结出来。可以把它发到博客里,或者发到美剧对应的社区或者贴吧里去,会比一般的影迷手工
总结的快很多。
通过英文剧集、电影学单词的小工具
我平时很喜欢看美剧和电影。而如果看中文字幕(看英文字幕也是一样)的话,注意力就会集中于阅读文字、理解剧情,练习听力的目的就落空了。而如果不看字幕的话,对话中
的很多生词就会随着对句子的大致理解而溜过去了,所以最好的办法就是看之前把对白中会出现的单词预览一次以为预习,看的过程中再熟悉一次,看完之后还可以针对用得到的
单词再记一次。为了实现这个目的,我写了一个小程序。
使用方式如下:
运行 WordsViaSubtitle.exe
可以通过程序中的搜索框搜索字幕文件(是射手网提供的,赞美射手 O(∩_∩)O哈!!)
easyMule自动关机工具(可用于1.X和2.0版本)
前几天发的程序只可以用于easyMule1.X版本,今天改写了一下,可以适用于2.0
使用方法:
运行 EasyMulePowerOff.exe
会提示您设置电驴的安装路径,设置好之后会检查到有没有未完成的任务:
显示我有一个未完的任务,看一下电驴中
电驴(easyMule)自动关机工具
由于电驴官方鼓励尽量多的上传,所以不提供下载完关机的功能。于是我自己写了个小工具来实现这个功能。
使用方法:
运行 EasyMulePowerOff.exe
会提示您设置电驴的安装路径,设置好之后会检查到有没有未完成的任务:
《Head First C#》将停止翻译和更新
近日闻悉国内某出版社即将出版《 Head First C# 》的中文版,为避免版权纠纷,本“山寨”系列将停止翻译和更新。
从去年 10 月开始利用课余时间翻译这本书,到现在翻译完了将近 13 章,总计 12 万余字。
剩余的正文内容已不足百页,无法做到有始有终,颇为遗憾。
感谢 CSDN 和 VeryCD 各位朋友一直以来的关注、支持、鼓励和批评。
2009 年 8 月 7 日
格物致知--《Effective C#》读书笔记--验证接口引用指向装箱后的值类型时无需拆箱
欲验证的结论: 接口引用指向装箱后的值类型时无需拆箱 。
代码如下:
1 | interface SomeInterface |
其中 OneValueType 是值类型,它实现了 SomeInterface 。
两个方法 CastStruct 和 CastInterface 分别把装箱之后的值类型转型为 OneValueType 和
SomeInterface 。预计的结果是第二个方法无需拆箱,查看 IL 来验证:
这是 CastStruct ():
格物致知--《Effective C#》读书笔记--验证四种判等方式
原地址在我的CSDN
Blog:http://blog.csdn.net/cuipengfei1/archive/2009/07/19/4362245.aspx
① Object 的静态方法 ReferenceEquals :
只适用于判断两个引用是否指向同一个实例,不适用于值类型(或者说用于值类型是没意义的,因为永远返回 false )。如下:
1 | TestEqual te = new TestEqual (); |
b1 为 true , b2 为 false 。 b2 为 false 的原因是两个整型值 1 装箱之后是两个不同的
Object 实例。
② Object 中定义的实例级虚方法 Equals :
格物致知 《Effective C#》读书笔记--验证类型转换
as 看起来很好用的样子,不会抛出异常,只要根据返回值是否为 null来做不同的处理就可以了。但是它也不是万金油,以下的情况 as 就不适用:
①值类型
比如:
1 | double d = 100.0; |
这两句代码就直接通不过编译,给出的原因是: as 运算符必须用于引用类型或可以为 null类型 (“int” 是一种不可以为 null
值的类型 )
想一下也合理, as 在失败时会返回 null,而值类型是不可以为 null的( INullable 除外)。
三种方式统计string中出现次数最多的char(还是LinQ最简便)
1 | using System; |