C#:如何实现和使用 NotNull 和 CanBeNull 属性

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/792531/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 01:18:50  来源:igfitidea点击:

C#: How to Implement and use a NotNull and CanBeNull attribute

c#attributesnull

提问by Svish

I want to let programmers and myself know that a method does not want nulland if you do send nullto it anyways, the result will not be pretty.

我想让程序员和我自己知道一个方不想要null,如果你确实发送null给它,结果不会很漂亮。

There is a NotNullAttributeand a CanBeNullAttributein Lokad Shared Libraries, in the Lokad.Qualitynamespace.

Lokad Shared Libraries中,命名空间中有 aNotNullAttribute和 a 。CanBeNullAttributeLokad.Quality

But how does that work? I looked at the source-code of those two attributes, and it looks like this:

但这如何运作?我查看了这两个属性的源代码,它看起来像这样:

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Parameter |
                AttributeTargets.Property | AttributeTargets.Delegate |
                AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
[NoCodeCoverage]
public sealed class NotNullAttribute : Attribute
{
}

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Parameter |
                AttributeTargets.Property | AttributeTargets.Delegate |
                AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
[NoCodeCoverage]
public sealed class CanBeNullAttribute : Attribute
{
}

Two empty classes inheriting from Attribute. How are they used? Do you have to look up xml-documentation and know that it is there? Cause I tried to both make my own copy of the attribute and to use the Lokad version, but when I tried to send a null directly in, I got no message. Neither from ReSharper nor from VS. Which I kind of expected actually. But how are they used? Can I somehow make VS generate warnings for me if I try to send something that is null in there? Or is it just used in some kind of testing framework? Or?

继承自 的两个空类Attribute。它们是如何使用的?您是否必须查找 xml 文档并知道它在那里?因为我尝试制作自己的属性副本并使用 Lokad 版本,但是当我尝试直接发送空值时,我没有收到任何消息。既不是来自 ReSharper,也不是来自 VS。我实际上有点期待。但是它们是如何使用的呢?如果我尝试在其中发送空值,我可以以某种方式让 VS 为我生成警告吗?或者它只是用于某种测试框架?或者?

采纳答案by Marc Gravell

In the mid-term, "code contracts" (in 4.0) will be a better answer to this. They are available now (with academicor commerciallicences), but will be more integrated in VS2010. This can provide both static analysis and runtime support.

在中期,“代码契约”(在 4.0 中)将是一个更好的答案。它们现在可用(具有学术商业许可证),但将更多地集成到 VS2010 中。这可以提供静态分析和运行时支持。

(edit) example:

(编辑)示例:

Contract.RequiresAlways( x != null );

Simple as that... the code contracts engine works at the IL level, so it can analyse that and throw warnings/errors from calling code during build, or at runtime. For backwards compatibility, if you have existing validation code, you can just tell it where the sanity checking ends, and it'll do the rest:

就这么简单……代码契约引擎在 IL 级别工作,因此它可以分析并在构建期间或运行时调用代码抛出警告/错误。为了向后兼容,如果您有现有的验证代码,您只需告诉它健全性检查在哪里结束,剩下的事情就交给它了:

if ( x == null ) throw new ArgumentNullException("x");
Contract.EndContractBlock();

回答by Anton Gogolev

This can be done either with AOP, whereby an Advice verifies at run-time whether a method parameter is null and whether nulls are allowed. See PostSharpand Spring.NETfor AOP.

这可以通过AOP来完成,其中 Advice 在运行时验证方参数是否为空以及是否允许空值。对于 AOP,请参阅PostSharpSpring.NET

As for ReSharper, see Annotated Framework:

至于 ReSharper,请参阅Annotated Framework

We have analyzed a great share of .NET Framework Class Library, as well as NUnit Framework, and annotated it through external XML files, using a set of custom attributes from the JetBrains.Annotations namespace, specifically:

  • StringFormatMethodAttribute (for methods that take format strings as parameters)
  • InvokerParameterNameAttribute (for methods with string literal arguments that should match one of caller parameters)
  • AssertionMethodAttribute (for assertion methods)
  • AssertionConditionAttribute (for condition parameters of assertion methods)
  • TerminatesProgramAttribute (for methods that terminate control flow)
  • CanBeNullAttribute (for values that can be null)
  • NotNullAttribute (for values that can not be null)

我们分析了 .NET Framework 类库和 NUnit Framework 的很大一部分,并通过外部 XML 文件对其进行了注释,使用来自 JetBrains.Annotations 命名空间的一组自定义属性,特别是:

  • StringFormatMethodAttribute(用于将格式字符串作为参数的方)
  • InvokerParameterNameAttribute(用于具有应与调用者参数之一匹配的字符串文字参数的方)
  • AssertionMethodAttribute(用于断言方)
  • AssertionConditionAttribute(用于断言方的条件参数)
  • TerminatesProgramAttribute(用于终止控制流的方)
  • CanBeNullAttribute(对于可以为 null 的值)
  • NotNullAttribute(对于不能为空的值)

回答by Michael Freidgeim

As pointed by Anton Gogolev, attributes can be created using PostSharp.(note that CodeContract is using static method calls inside body of method)

正如Anton Gogolev所指出的,可以使用 PostSharp 创建属性。(注意 CodeContract 在方体内使用静态方调用)

UPDATE Feb 2013: new 3.0 release of PostSharp (currently in Beta) will support Validating parameters, fields and properties

2013 年 2 月更新:PostSharp 的新 3.0 版本(目前处于 Beta 版)将支持 验证参数、字段和属性

1) Article validate-parameters-using-attributeshas implementation of

1) 文章validate-parameters-using-attributes有实现

public class NotEmpty : ParameterAttribute

public class NotNull : ParameterAttribute

[AttributeUsage(AttributeTargets.Parameter)]

public abstract class ParameterAttribute : Attribute

{

public abstract void CheckParameter(ParameterInfo parameter, object value); 

}

公共类 NotEmpty : ParameterAttribute

公共类 NotNull : ParameterAttribute

[AttributeUsage(AttributeTargets.Parameter)]

公共抽象类 ParameterAttribute : 属性

{

public abstract void CheckParameter(ParameterInfo parameter, object value); 

}

It also Required a method attribute with a method boundary aspect to process the parameter attributes.

它还需要具有方边界方面的方属性来处理参数属性。

2) In the comment to the article there are links to very similar implementationfor?NonNull/NonEmpty? ??

2)在对文章的评论中有指向非常相似的实现的链接?NonNull/NonEmpty???

[return: NonNull] public SomeObject SomeMethod([NonNull] AnotherObject param1)? ?? ?

[返回:NonNull] public SomeObject SomeMethod([NonNull] AnotherObject param1)??? ?

The source code is?located In?google code Torch/DesignByContract

源代码位于?谷歌代码 Torch/DesignByContract

3) another more complicate example is described in?http://badecho.com/2011/11/validating-method-parameters-with-postsharp/? ? ? ?

3) 另一个更复杂的例子在? http://badecho.com/2011/11/validating-method-parameters-with-postsharp/?? ? ?

回答by citizenmatt

These annotations are for ReSharper, and are copied from the JetBrains.Annotations namespace. A framework can put them in their own namespace, however, ReSharper will NOT pick up these annotations automatically - you need to tell ReSharper to use the custom namespace in the options dialog. Once you've selected the new namespace, ReSharper's analysis will pick up the attributes and give you highlights and warnings.

这些注释用于 ReSharper,从 JetBrains.Annotations 命名空间复制而来。框架可以将它们放在自己的命名空间中,但是,ReSharper 不会自动选取这些注释 - 您需要告诉 ReSharper 在选项对话框中使用自定义命名空间。选择新命名空间后,ReSharper 的分析将选取属性并为您提供突出显示和警告。