发布于 2018-03-20 11:54 更新于 2018-03-20 12:35
多人协作开发的项目总会遇到代码编写风格上的差异。一般工具都能帮我们将常见的差异统一起来——例如 if
的换行;但也有一些不那么通用,但项目中却经常会出现的写法也需要统一。
例如将单元测试中的 Assert.AreEqual(foo.GetType(), typeof(Foo));
换成 Assert.IsInstanceOfType(foo, typeof(Foo));
。
阅读本文将学习如何使用 ReSharper 的 Custom Pattern 功能来完成这样的警告和转换。
我们团队中自定义了一个代码风格规范,在单元测试中 Assert.AreEqual(foo.GetType(), typeof(Foo));
应该被换成 Assert.IsInstanceOfType(foo, typeof(Foo));
。于是,ReSharper 会给出警告,并给出推荐的写法;如果遵循 ReSharper 的建议,ReSharper 将自动为我们修改代码。
▲ 给出警告,并提供建议
▲ 可以遵循建议
▲ 然后代码就被修改成我们建议的写法了
我们需要打开 ReSharper 的选项窗口,然后在里面找到“自定义模式”:
点击“Add Pattern”之后,我们就可以开始编写 Custom Pattern 了。
为了快速开始,可以将下面的两行代码分别复制到两个黑框中。(如果你只看到了一个黑框,请在右上角将“Find”按钮切换到“Replace”按钮。)
// 将下面这一句话复制到第一个黑色框中。
Assert.AreEqual($instance$.GetType(), typeof($type$));
// 将下面这一句话复制到第二个黑色框中。
Assert.IsInstanceOfType($instance$, typeof($type$));
这时,占位符框中就会出现我们编写的两个占位符:
▲ 占位符列表
我们需要将 instance
占位符从表达式修改为标识符:
解释一下这几项的意思:
foo.Bar()
,注意,分号并不是表达式的一部分。if (foo is null) throw new ArgumentNullException(nameof(foo));
,注意,分号属于语句的一部分。Foo
,或者 Walterlv.Demo.Foo
。确定之后我们填写其他的信息:
AssertEqualToInstanceOfType
// ReSharper disable once AssertEqualToInstanceOfType
[SuppressMessage("ReSharper", "AssertEqualToInstanceOfType")]
建议简化成 InstanceOfType 以提升可读性。
简化成 InstanceOfType
设置完之后,“Edit Highlighting Pattern”窗口应该是这样的:
当然,在“Custom Pattern”列表中也可以统一设置所有模式的警告级别。
最后,把这些规则保存到团队共享中,那么所有安装了 ReSharper 的此项目的团队成员都将遵循这一套规则。
Custom Pattern 功能只是为了给我们一个格式转换吗?才不止是这样哦!它能够帮助我们发现一些潜在的错误。
例如使用 MSTestEnhancer 进行单元测试时,如果使用了它推荐的单元测试风格,就应该配套使用 ContractTestCase
特性,如果不这么写,必定意味着错误。
于是,我们可以编写一个自定义模式来发现和修改这样的错误。
你认为可以怎么写呢?我在下面给出了我的写法。你还可以发掘出更多的潜能吗?非常期待!
本文会经常更新,请阅读原文: https://walterlv.com/post/analyze-and-fix-code-using-resharper-custom-pattern.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名 吕毅 (包含链接: https://walterlv.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 (walter.lv@qq.com) 。