显式实现接口的 ReSharper 文件布局
Posted
技术标签:
【中文标题】显式实现接口的 ReSharper 文件布局【英文标题】:ReSharper File Layout for explicit implemented interfaces 【发布时间】:2020-03-04 08:06:54 【问题描述】:我正在尝试以这样一种方式配置 ReSharper 的文件布局,即格式化代码确实遵守“StyleCop SA1202”规则。
更多信息请参见https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1202.md。
基本上,这条规则表示元素的顺序必须匹配给定的模式。 首先是“公共”,然后是“内部”...
当我有一个实现显式接口的类时,它实际上是“公共的”。 见以下代码:
void IDisposable.Dispose()
// Implementation
当我使用以下配置配置 ReSharper 文件布局时:
<Entry DisplayName="Methods">
<Entry.Match>
<Kind Is="Method" />
</Entry.Match>
<Entry.SortBy>
<Access Order="Public Internal Protected" />
</Entry.SortBy>
</Entry>
显式实现的接口放在任何公共方法之后。
有没有办法配置 ReSharper 的文件布局,以便在使用显式接口实现时遵守规则 SA1202?
亲切的问候
【问题讨论】:
【参考方案1】:我正在使用 StyleCop 文件布局,并在最后添加了一条 Dispose 方法的特殊规则:
<?xml version="1.0" encoding="utf-16"?>
<Patterns
xmlns="urn:schemas-jetbrains-com:member-reordering-patterns">
<TypePattern DisplayName="Non-reorderable types">
<TypePattern.Match>
<Or>
<And>
<Kind Is="Interface" />
<Or>
<HasAttribute Name="System.Runtime.InteropServices.InterfaceTypeAttribute" />
<HasAttribute Name="System.Runtime.InteropServices.ComImport" />
</Or>
</And>
<Kind Is="Struct" />
<HasAttribute Name="JetBrains.Annotations.NoReorderAttribute" />
<HasAttribute Name="JetBrains.Annotations.NoReorder" />
</Or>
</TypePattern.Match>
</TypePattern>
<TypePattern DisplayName="xUnit.net Test Classes" RemoveRegions="All">
<TypePattern.Match>
<And>
<Kind Is="Class" />
<HasMember>
<And>
<Kind Is="Method" />
<HasAttribute Name="Xunit.FactAttribute" Inherited="True" />
</And>
</HasMember>
</And>
</TypePattern.Match>
<Entry DisplayName="Setup/Teardown Methods">
<Entry.Match>
<Or>
<Kind Is="Constructor" />
<And>
<Kind Is="Method" />
<ImplementsInterface Name="System.IDisposable" />
</And>
</Or>
</Entry.Match>
<Entry.SortBy>
<Kind Order="Constructor" />
</Entry.SortBy>
</Entry>
<Entry DisplayName="All other members" />
<Entry DisplayName="Test Methods" Priority="100">
<Entry.Match>
<And>
<Kind Is="Method" />
<HasAttribute Name="Xunit.FactAttribute" />
</And>
</Entry.Match>
<Entry.SortBy>
<Name />
</Entry.SortBy>
</Entry>
</TypePattern>
<TypePattern DisplayName="NUnit Test Fixtures" RemoveRegions="All">
<TypePattern.Match>
<And>
<Kind Is="Class" />
<HasAttribute Name="NUnit.Framework.TestFixtureAttribute" Inherited="True" />
</And>
</TypePattern.Match>
<Entry DisplayName="Setup/Teardown Methods">
<Entry.Match>
<And>
<Kind Is="Method" />
<Or>
<HasAttribute Name="NUnit.Framework.SetUpAttribute" Inherited="True" />
<HasAttribute Name="NUnit.Framework.TearDownAttribute" Inherited="True" />
<HasAttribute Name="NUnit.Framework.FixtureSetUpAttribute" Inherited="True" />
<HasAttribute Name="NUnit.Framework.FixtureTearDownAttribute" Inherited="True" />
</Or>
</And>
</Entry.Match>
</Entry>
<Entry DisplayName="All other members" />
<Entry DisplayName="Test Methods" Priority="100">
<Entry.Match>
<And>
<Kind Is="Method" />
<HasAttribute Name="NUnit.Framework.TestAttribute" />
</And>
</Entry.Match>
<Entry.SortBy>
<Name />
</Entry.SortBy>
</Entry>
</TypePattern>
<TypePattern DisplayName="StyleCop Classes, Interfaces, & Structs" RemoveRegions="All">
<TypePattern.Match>
<Or>
<Kind Is="Class" />
<Kind Is="Struct" />
<Kind Is="Interface" />
</Or>
</TypePattern.Match>
<Entry DisplayName="Constants">
<Entry.Match>
<Kind Is="Constant" />
</Entry.Match>
<Entry.SortBy>
<Access Order="Public Internal ProtectedInternal Protected Private" />
<Static />
<Readonly />
</Entry.SortBy>
</Entry>
<Entry DisplayName="Fields">
<Entry.Match>
<Kind Is="Field" />
</Entry.Match>
<Entry.SortBy>
<Access Order="Public Internal ProtectedInternal Protected Private" />
<Static />
<Readonly />
</Entry.SortBy>
</Entry>
<Entry DisplayName="Constructors">
<Entry.Match>
<Kind Is="Constructor" />
</Entry.Match>
<Entry.SortBy>
<Access Order="Public Internal ProtectedInternal Protected Private" />
<Static />
<Readonly />
</Entry.SortBy>
</Entry>
<Entry DisplayName="Destructors">
<Entry.Match>
<Kind Is="Destructor" />
</Entry.Match>
<Entry.SortBy>
<Access Order="Public Internal ProtectedInternal Protected Private" />
<Static />
<Readonly />
</Entry.SortBy>
</Entry>
<Entry DisplayName="Delegates">
<Entry.Match>
<Kind Is="Delegate" />
</Entry.Match>
<Entry.SortBy>
<Access Order="Public Internal ProtectedInternal Protected Private" />
<Static />
<Readonly />
</Entry.SortBy>
</Entry>
<Entry DisplayName="Events">
<Entry.Match>
<Kind Is="Event" />
</Entry.Match>
<Entry.SortBy>
<Access Order="Public Internal ProtectedInternal Protected Private" />
<Static />
<Readonly />
</Entry.SortBy>
</Entry>
<Entry DisplayName="Enums">
<Entry.Match>
<Kind Is="Enum" />
</Entry.Match>
<Entry.SortBy>
<Access Order="Public Internal ProtectedInternal Protected Private" />
<Static />
<Readonly />
</Entry.SortBy>
</Entry>
<Entry DisplayName="Interfaces">
<Entry.Match>
<Kind Is="Interface" />
</Entry.Match>
<Entry.SortBy>
<Access Order="Public Internal ProtectedInternal Protected Private" />
<Static />
<Readonly />
</Entry.SortBy>
</Entry>
<Entry DisplayName="Properties">
<Entry.Match>
<Kind Is="Property" />
</Entry.Match>
<Entry.SortBy>
<Access Order="Public Internal ProtectedInternal Protected Private" />
<Static />
<Readonly />
</Entry.SortBy>
</Entry>
<Entry DisplayName="Indexers">
<Entry.Match>
<Kind Is="Indexer" />
</Entry.Match>
<Entry.SortBy>
<Access Order="Public Internal ProtectedInternal Protected Private" />
<Static />
<Readonly />
</Entry.SortBy>
</Entry>
<Entry DisplayName="Methods">
<Entry.Match>
<Kind Is="Method" />
</Entry.Match>
<Entry.SortBy>
<Access Order="Public Internal ProtectedInternal Protected Private" />
<Static />
<Readonly />
</Entry.SortBy>
</Entry>
<Entry DisplayName="Structs">
<Entry.Match>
<Kind Is="Struct" />
</Entry.Match>
<Entry.SortBy>
<Access Order="Public Internal ProtectedInternal Protected Private" />
<Static />
<Readonly />
</Entry.SortBy>
</Entry>
<Entry DisplayName="Classes">
<Entry.Match>
<Kind Is="Class" />
</Entry.Match>
<Entry.SortBy>
<Access Order="Public Internal ProtectedInternal Protected Private" />
<Static />
<Readonly />
</Entry.SortBy>
</Entry>
<Entry DisplayName="Dispose">
<Entry.Match>
<Name Is="Dispose" />
</Entry.Match>
<Entry.SortBy>
<Access Order="Public Internal ProtectedInternal Protected Private" />
<Static />
<Readonly />
</Entry.SortBy>
</Entry>
</TypePattern>
</Patterns>
【讨论】:
【参考方案2】:您可以创建一个新区域,在其中捕获私有属性并实现接口,并在接口名称中使用正则表达式“I.*”
<Region Name="Explicit interface implementation">
<Entry DisplayName="Interface properties">
<Entry.Match>
<And>
<Kind Is="Property" />
<ImplementsInterface Name="I.*" />
<Access Is="Private" />
</And>
</Entry.Match>
</Entry>
</Region>
【讨论】:
以上是关于显式实现接口的 ReSharper 文件布局的主要内容,如果未能解决你的问题,请参考以下文章
尽管有ReSharper [NotNull]注释,我应该添加显式空值检查吗?