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

我想让程序员和我自己知道一个方法不需要null ,如果你真的发送null ,结果将不会很漂亮。

Lokad.Quality命名空间中的Lokad共享库中有一个NotNullAttribute和一个CanBeNullAttribute

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

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

两个从Attributeinheritance的空类。 他们如何使用? 你必须查找XML文档,并知道它在那里? 因为我试图使我自己的属性的副本,并使用Lokad版本,但是当我试图直接发送null,我没有消息。 无论是从ReSharper还是从VS. 这实际上是我所期望的 但他们是如何使用的? 我可以以某种方式让VS为我生成警告,如果我尝试发送那里是空的东西吗? 还是只是在某种testing框架中使用? 要么?

从中期来看,“代码合同”(4.0版)将会是更好的答案。 他们现在( 学术或商业许可证),但将更多地集成在VS2010中。 这可以提供静态分析和运行时支持。

(编辑)例子:

 Contract.RequiresAlways( x != null ); 

这么简单…代码契约引擎在IL级别工作,所以它可以在构build期间或运行时分析调用代码中的警告/错误。 为了向后兼容,如果您有现有的validation代码,您可以告诉它完整性检查结束的位置,剩下的工作就完成了:

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

这可以通过AOP来完成,通过这个通知,运行时通知会validation方法参数是否为空,以及是否允许空值。 有关AOP,请参阅PostSharp和Spring.NET 。

至于ReSharper,请参阅Annotated Framework :

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

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

这些注释用于ReSharper,并从JetBrains.Annotations命名空间复制。 一个框架可以把它们放在他们自己的名字空间中,但是,ReSharper不会自动select这些注释 – 你需要告诉ReSharper在选项对话框中使用自定义名称空间。 一旦你select了新的命名空间,ReSharper的分析将会提取这些属性并给你提供亮点和警告。

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

2013年2月更新:PostSharp 3.0新版本(目前处于testing阶段)将支持validation参数,字段和属性

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

公共类NotEmpty:ParameterAttribute

公共类NotNull:ParameterAttribute

[AttributeUsage(AttributeTargets.Parameter)]

公共抽象类ParameterAttribute:Attribute

{

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

}

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

2)在文章的评论中,有非常类似于 NonNull / NonEmpty的实现的链接

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

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

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

Interesting Posts