如何配置 ReSharper 以接受 [Required](来自 PostSharp)等同于 [NotNull](反之亦然)?

How can I configure ReSharper to accept [Required] (from PostSharp) as equivalent to [NotNull] (or vice versa)?

我在各种项目中同时使用 PostSharp 和 ReSharper,具体来说,为了获得更好的代码,我同时使用了 PostSharp 的代码契约执行和 ReSharper 的注释。

问题是,当涉及到可空性时,我最终得到了很多参数等,声明如下所示:

public void Foo ([Required] [JetBrains.Annotations.NotNull] object bar)

...为了既强制执行前者又注释后者 bar 不能为空。

有没有一种方法可以将 ReSharper 配置为将 [Required] 属性的存在视为等同于 [NotNull] 用于注释目的,或其他一些方法(我不特别说明如何)以避免必须像这样为每个非空参数重复自己,等等?

this documentation page 所述,ReSharper 实际上可以识别自定义注释,即使它们是在 "JetBrains.Annotations" 以外的命名空间中定义的。因此,您可以定义自己的自定义注释,并将其中一些注释转换为将代码契约应用于目标元素的方面提供程序。

首先,打开"ReSharper Options" | "Code Annotations" 并单击 "Copy C# implementation to clipboard"。此外,取消选中 "internal" 以跨项目重复使用注释。

然后新建一个代码文件,贴上注释。您可以重命名命名空间(例如 MyAnnotations)。如果您选择使用自定义命名空间,您需要再次打开 "ReSharper Options" 并 select 在 "Custom namespaces should be marked in the list below".

中自定义命名空间旁边的复选框

现在您可以找到 NotNullAttribute 并按以下方式更改其源代码:

public sealed class NotNullAttribute : LocationLevelAspect, IAspectProvider
{
    public IEnumerable<AspectInstance> ProvideAspects(object targetElement)
    {
        var requiredConstruction = new ObjectConstruction( typeof( PostSharp.Patterns.Contracts.RequiredAttribute ) );
        yield return new AspectInstance( targetElement, requiredConstruction, null );
    }
}

您可以在您的代码中应用此自定义属性,它将同时用作 PostSharp 方面和 ReSharper 注释。

public void Foo ([MyAnnotations.NotNull] object bar)

AlexD 在技术上已经回答了这个问题,但这只是因为原始问题中存在错误的假设。 PostSharp.Required 属性不等同于 JetBrains.NotNull。 NotNull 的意思就是这样,而 Required 的意思既不是 null 也不是空的。

AlexD 的方法是修改 JetBrains NotNull 属性,使其表现得像 Required 属性,然后改用它。但是 JetBrains 没有 Required 的等价物,所以如果你想为 "not null" 和 "neither null nor empty" 保留两个不同的属性,并且同时让 Resharper 尊重这两个属性,那么这种方法是行不通的。