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

发布于 2024-07-18 05:38:55 字数 1212 浏览 4 评论 0原文

我想让程序员和我自己知道,某个方法不需要 null,并且如果您无论如何都向它发送 null,结果将不会很漂亮。

Lokad 共享库< 中有一个 NotNullAttributeCanBeNullAttribute /a>,位于 Lokad.Quality 命名空间中。

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

[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
{
}

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

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

There is a NotNullAttribute and a CanBeNullAttribute in Lokad Shared Libraries, in the Lokad.Quality namespace.

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

锦欢 2024-07-25 05:38:55

从中期来看,“代码契约”(4.0 中)将是对此的更好答案。 它们现已推出(学术商业 许可证),但将在 VS2010 中更加集成。 这可以提供静态分析和运行时支持。

(编辑)示例:

Contract.RequiresAlways( x != null );

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

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

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

(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:

if ( x == null ) throw new ArgumentNullException("x");
Contract.EndContractBlock();
眼眸 2024-07-25 05:38:55

这可以通过 AOP 来完成,其中建议在运行时验证方法参数是否是null 以及是否允许 null。 请参阅 PostSharpSpring .NET 用于 AOP。

至于 ReSharper,请参阅带注释的框架

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

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

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 PostSharp and Spring.NET for AOP.

As for ReSharper, see 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)
给妤﹃绝世温柔 2024-07-25 05:38:55

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

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.

素年丶 2024-07-25 05:38:55

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

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

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

公共类NotEmpty:ParameterAttribute

公共类NotNull:ParameterAttribute

[AttributeUsage(AttributeTargets.Parameter)]

公共抽象类ParameterAttribute:属性

{

public abstract void CheckParameter(ParameterInfo 参数,对象值);  
  

}

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

2) 在文章的评论中,有非常相似的实现< /a> 对于非空/非空    

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

源代码位于google code Torch /DesignByContract

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

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

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

1) Article validate-parameters-using-attributes has implementation of

public class NotEmpty : ParameterAttribute

public class NotNull : ParameterAttribute

[AttributeUsage(AttributeTargets.Parameter)]

public abstract class ParameterAttribute : Attribute

{

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 implementation for NonNull/NonEmpty    

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

The source code is located In google code Torch/DesignByContract

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文