学舌一点说, 这世界上使用VS Studio的程序员分两类, 用Resharper的, 和不用的.
对vim狂热如我者, 初用IDE 是不喜欢的, 抵触的, 也赖得花时间琢磨它的复杂功能, 但是, 世界上再好的东西也难免在所有领域所有时间都一枝独秀, .NET之难, 不在于C#/VB.NET作为一种新的语言, 重头戏是3000个庞大的类库, 而在使用这个类库时, 你得时不时停下编码, 查找有没有一个类/方法/属性是你眼下正要用的. 对于这一个重要的需求, IDE中的Intellisense 做了件极好但尚不完美的一件事, 而Vim中做到这个, 几近不可能, 虽然vim最新版中出现了叫做的Omni Complete的可编程补齐功能, 仍是几近不可能, 然而, 总有人站出来完成你认为不可能的事, 它是sourceforge 上一个项目, 为java/.NET以及其它几种象XML这样的东西做了类似VS中Intellisense的效果, 第一印象效果是让人目瞪口呆的, 你会再次感叹开源社区的人才济济, 其想象之大胆, 创造力之汹涌澎湃连绵不绝, 它弹出的不是vim原先的基于字符界面的补齐, 而是跟IDE中几乎一模一样的窗口, 显示着可能的候选项, 选中一项, 其文档说明也会列在旁边. 然而, 然而, 真实世界里总是有不停的转折, 只要你往前继续摸索, 总会发现好的东西中也有差强人意的地方, 这个功能毕竟还不够完美, 不稳定, 对你自己写的代码无法做补齐, 弹出的窗口甚至也没有考虑不是显示的位置超出了窗口的可视区域, 总之, 往细节去考量, 发现离VS IDE中的功能距离尚远. 但是, 不要轻易结论, 也不要随便开始失望, 作成这样已经非常之不易, 何况, 中国人习惯的跟贴: 有本事你做一个! .... 做人要厚道.
我奇怪象我这样整天挂在网上的人对有用信息的摄取之如此无效, 只因为我对Resharper相见恨晚.
在网上搜索和考评对VS Studio中编程真正有用的插件时, 有一些不错的东西: Assist X, Code Smith,Code Rush, DPack, Resharper.
象Resharper一样获得如此广泛的好评, 如此卓然独立地超出第二名一大截的东西, 实不多见.
几乎所有对上述同类产品试过一遍的人都一致赞同resharper是最好的, 而这个最还不是体育解说中常说的微弱优势, 是压倒性优势.
有人说, 如果用Resharper是一种错误, 那他就不想正确.
有人说, 如果他不能用Resharper, 他就不再写.NET程序.
我想列点具体的, 说说为什么它是如此之"好", 以及所缺憾的那0.001% 是什么.
■ 代码正确性校验, 或者说是后台编译. 它后台编译的目的是为了标出你的代码中的所有错误, 而不是为了替代你用IDE中的build命令生成最终的目标文件. 众所周知, VS2003中的Ctrl+Shift+B 开始的编译过程很漫长, 而且reference的依赖关系处理不当, 经常发生某个文件被占用导致你无法生成目标文件的情况, 而如果你的代码中有错, 你这一趟算是白干了, 改完之后还得再编一遍. 有了resharper的后台编译, 所有原来由C#编译器编译之后才报告的错误直接就在代码中以不同颜色高亮显示出来了. 你可以做到不需要频繁编译, 而能保证最终的一次编译99.999%是没有一个错误的, 我说99.999%, 实际上还并没有碰到那0.001%的情况. 它的检查是如此全面, 如此深入, 因为连 string.Format中{0}, {1}与后面参数的不匹配这样的语义上潜在的错误都能报出来, 这让我想到了gcc编译器对能printf / scanf中的%d, %s 所做的深度检查, 一句话, 好事被做的如此决绝彻底!
■ 更正建议. 如果你突然想用 RegularExpression, 但没有事先在文件头加上using System.Text; 那你需要做的是到文件开头, 加上这句, 再回到刚才编缉的地方继续, 心细一点的, 离开当前编辑位置时会设一个bookmark(Ctrl+k, Ctrl+k), 加完using语句后用 Ctrl+K, Ctrl+N 向下遍历所有的bookmark可以再直观地回来, 回来后可能还需要再用Ctrl+k, Ctrl+k把bookmark去掉, 它的使命已经完成. 或者, 在你大脑的高速缓存中记下当前的行号, 用Ctrl+G 直接回到这一行, 这个方法再高效, 但是有可能需要把你大脑里原来位于高速缓存中的其它内容交换到次级存储上, 而有了resharper, 它会在你输入完RegularExpression.之后把其颜色标为红色, 显示一个tooltip, 告诉你按Alt + Enter加入所缺的名字空间, 你只需要一个按键, 光标位置纹丝不动, 一切都已经搞掂了, 你继续你的代码, 它保障不必要的东西不去打断你要干的正事.
■ 比微软更好的IntelliSense. 微软的IntelliSense已经是一件很了不起的功能, Resharper再度把它磨光擦亮, 镶上宝石. 有了Resharper, 只要任何一个字母被输入, 相应的建议马上就列出来, 其中还包括关键字, 比如 continue; 而微软的IntelliSense 字典里是没有关键字的. 对匹配内容进行过滤, 不匹配的就不显示在列表里了. 对重载的函数的所有候选版本同时列在一个提示窗口中, 而不象微软一样一次只列一个, 这样的好处是你直接就能点选你最想要的那个版本.
◆ Hashtable hash = new
此时按下Ctrl+Shift+Space, 会直接补齐后面的 Hashtable(); 因为编译器有办法知道构造函数没有参数.
◆ Size s = ( size_hash[ "button" ];
(之后按Ctrl + Shift + Space会补齐 (Size)作为 cast
◆ Button btn = size_controls[ "button" ] as ;
as 之后按Ctrl+Shift+Space 会补齐Button
■ 更方便的code navigation.◆ Ctrl+Shift+ Backspace 回到上一次真正发生过修改的地方, vim中的g;
◆ 所有的override函数左边显示一个小图标, 点击它会直接跳转到它所override的基类中的函数定义处, 这可以让派生类的作者方便地查看基类定义者在代码中的文档.
◆ Alt + F7 分析一个标识符所有被引用的地方, 对于变量, 对它的读取和对它的体赋值被标以不同的颜色, 对于想查找某个变量在何处被修改非常有用.
◆ Ctrl+Shift+F7, 高亮显示最后一次被查找的标识符
◆ Shift + Alt + F7 对标识符的使用进行高级查找.
◆ Alt + 下箭头, 到下一个函数处, 它以函数为单位进行遍历, 当然Alt + 上箭头就不用说了
◆ F12, Shift+F12, 向下/下遍历所有代码中被标以警告的地方. 这个键覆盖了微软原来的定义: 跳到变量的定义处. Resharper 把这功能绑定到了 Crl + B
◆ Ctrl + Shift + T, 查看类定义.
假如你在另一个文件中定义了自己的类, MyClass, 在当前文件中使用了这个类如下:
MyClass bad_name ;
然后在离定义八丈远的地方查看代码时发现了一个 bad_name, 无从知晓它的类型, 需要把鼠标悬停其上, 等待提示的ToolTip窗口, 看完了ToolTip , 也只知道它是一个MyClass的类, 它具体干什么的你不知道, 你需要到这个类的定义处, 在bad_name上使用微软原来的F12 的功能, 你会跳转到前面声明 bad_name变量的地方, 然后, 再把光标置于MyClass上, 再按F12一次, 这才是你想要的, 在resharper中一个Ctrl + Shift + F12搞定
◆ Ctrl + N 打开一个窗口键入你想查看的类的部分名字, 底下动态变化的列表会显示匹配的名字.
◆ Ctrl + Shift + N 打开一个窗口键入你想查看的文件的部分名字. 跟上面的一项一直, 查找的范围是整个Solution, 加了微软自己的类库, 有了这两项功能, 你几乎不需要在大项目中拖着细细的滚动条查找你的项目, 你的文件, 你的类.
◆ Ctrl + E 打开一个你最近访问过的文件的列表, 很实用!
◆ 添加了 Close All, Close All But this, 尤其是这个Close All But this, 我猜想设计这一功能的人可能知道vim 中的Ctrl+W, o功能, 或Emacs中的Ctrl + X, 1, 非常实用, 没有这个很多程序员需要这么干: 在打开文件太多的情况下, 发现IDE变慢了, 而为了不逐个关闭其它文件, 索性关闭所有的, 毕竟微软有这么一个菜单项, 但还要再次找到眼下正在编辑的那个文件, 定位到你正在编辑的行. 有了这个Close All But this, 就只留下这个窗口, 其它的全部干掉!
■ 重构支持◆ 一个函数越写越大, 想把其中的一段代码抽取出去成为一个单独的辅助函数, 只需要选中这个代码块, 使用它的Extract method功能, resharper会分析你这段代码块中使用到了哪些局部变量, 从而推断出要抽取出的方法需要几个参数, 都是什么类型, 它用编译器所能做到的所有事情为节省了你的思考和编码
◆ 修改变量名, F2, 熟悉吧, 在Explorer中它是微软定义的修改文件名的快捷键. 可以修改的有函数参数, 类名, 函数名, field名, 局部变量名等等我没用过的.
修改类名时, 如果当前类所在的文件跟类同名, 它还会提示你是否把文件名也一块改了. 酷!
修改局部变量名时, 所有对这个局部变量的引用同时得到修改
修改函数参数时, XML文档中的
◆ 交换一对赋值
比如你在一个 Form 的ctor函数中根据一个序列化过的配置类初始化一个CheckBox 控件:
m_ckbox_show_tip_of_day_at_startp.Checked = Preference.Singleton.ShowTipOfDayAtStartup;
显然你需要在这个对话框按OK关闭时再把这个CheckBox的状态保存起来, 此时需要的是交换这两个赋值, 这在resharper以前是需要通过鼠标选取, 拖动来完成的. Resharper中的重构可以针对这个专门的需求交换等号两端的东西.
■ 代码模板, 环绕代码◆ 你写下一段代码, 突然想对它加上try/catch/finally的保护, 或者觉得它只应该在满足某个条件时才被执行, 你需要一个if, 或者你已经写了if + statement, 但由于一开始以为这个statement永远只是一个单独的语句所以没有{}, 但随后又意识到最好还是保持风格的一致, 那只需要在当前的statement行上(对于单行代码不需要先选中), 或选中这段代码, 按Ctrl + Alt + J, 点击其中列出来的模板即可.
◆ 添加自己的模板, 修改默认的模板. 系统默认的模板中 try...catch代码中的catch块是
Console.Write(e); 我更喜欢
catch(Exception ex)
{
Debug.Assert(false, ex.ToString() );
}
因为很多事件的hander中EventArgs参数已经被命名为了e, 所以我倾向与所有的异常变量都用ex, 可贵的可以通过修改模板来一劳永逸地做到.
■ 那0.001% 的东西◆ slow, slower, very slow, unbearable slow, fuck slow
有人说这是compile tax, 时间是resharper对后台编译所带来的好处所征的税. 你需要最新的resharper版本, 需要最快的电脑, 最大的内存, 我的经验, 512M内存, 2.8G CPU 能感觉到慢, 但尚可忍受, 尤其是有前面那么多诱人的功能时. 但我的确有同事机器配置较低, 不堪忍受它的慢就把它卸载了
◆ XML documentation中的 Tag补齐功能, 按
时会错误地开始一个新行, 而用鼠标双击就不会
◆ Ctrl + F12 打开一个类的所有成员的浏览窗口, 在这个窗口中本可以大有作为, 象Dpack作的那样, 对private/public/protected分类, 按field, method, property 分类, 搜索文字支持任意的文字片段等, DPack做到了, 尽管打开这个窗口很慢, 虽然跟Resharper一起时说不出是谁慢了.
◆ 没有DPack中的0-9 数字编号的bookmark, 跟上面的那个功能一起, 是我还留着DPack的唯二理由.
下面是一些应用实况的截图, 不言自明:
图1. DPack 的bookmark
图2: 高亮变量的使用
图3: 将一个表达式的值作为函数参数传入
图4: 显示重载的函数
图5: 显示类的成员列表, 跟DPack 逊了很多
图6: 安全删除一个变量