2009-04-27 12 views
38

Quiero que los programadores y yo sepamos que un método no quiere null y si envía null de todos modos, el resultado no será bueno.C#: Cómo implementar y usar un atributo NotNull y CanBeNull

Hay NotNullAttribute y CanBeNullAttribute en Lokad Shared Libraries, en el espacio de nombre Lokad.Quality.

Pero, ¿cómo funciona? Miré el código fuente de estos dos atributos, y se ve así:

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

Dos clases vacías que heredan de Attribute. ¿Cómo se usan? ¿Tienes que buscar la documentación xml y saber que está allí? Porque intenté hacer mi propia copia del atributo y usar la versión de Lokad, pero cuando traté de enviar un nulo directamente, no recibí ningún mensaje. Ni de ReSharper ni de VS. Lo que esperaba en realidad. Pero, ¿cómo se usan? ¿De alguna manera puedo hacer que VS genere advertencias para mí si trato de enviar algo que es nulo allí? ¿O solo se usa en algún tipo de marco de prueba? ¿O?

+1

Para comentar sobre su caso específico, esos atributos no hacen nada y son solo "documentación". Las otras respuestas dan buenas alternativas, sin embargo. – Sander

+3

'Nullable' es un nombre mejor para' CanBeNull', simplemente diciendo :) –

Respuesta

46

En el mediano plazo, los "contratos de código" (en 4.0) serán una mejor respuesta a esto. Están disponibles ahora (con licencias academic o commercial), pero estarán más integrados en VS2010. Esto puede proporcionar tanto análisis estático como soporte en tiempo de ejecución.

(editar) ejemplo:

Contract.RequiresAlways(x != null); 

Tan simple como eso ... el motor contratos de código funciona en el nivel de IL, por lo que puede analizar eso y lanzar advertencias/errores de código de llamada durante la construcción, o por lo tiempo de ejecución Para compatibilidad con versiones anteriores, si tiene código de validación existente, sólo se puede decir que cuando la cordura comprobar extremos, y que va a hacer el resto:

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

¡Parecía muy sencillo! ¿Funcionará en VS 2008 también? ¿Qué quieres decir con "más integrado"? – Svish

+0

Sí; los enlaces que publiqué fueron para la variante VS2008. Por "más integrado", me refiero a AFAIK, está integrado en el IDE y en el tiempo de ejecución, en lugar de ser un complemento separado. No lo he comprobado (de hecho, no puedo), pero esto * posiblemente * signifique que también funciona en la Edición Express (el complemento no). –

+0

Cool. ¿Ya probaste este complemento? Fácil de instalar y usar? ¿Es seguro usarlo en un entorno de producción? (¿Me matarán otros empleados si lo agrego?: P) – Svish

18

Esto se puede hacer ya sea con AOP, mediante el cual un Consejo verifica en tiempo de ejecución si un parámetro de método es nulo y si se permiten nulos. Ver PostSharp y Spring.NET para AOP.

En cuanto a ReSharper, ver Annotated Framework:

Hemos analizado una gran parte de .NET Framework biblioteca de clases, así como marco NUnit, y anotado a través de archivos XML externos, utilizando un conjunto de atributos personalizados de JetBrains.Anotaciones espacio de nombres, a saber:

  • StringFormatMethodAttribute (por métodos que toman las cadenas de formato como parámetros)
  • InvokerParameterNameAttribute (por métodos con argumentos literales de cadena que debe coincidir con uno de los parámetros de llamada)
  • AssertionMethodAttribute (para los métodos de afirmación)
  • AssertionConditionAttribute (para parámetros de condiciones de los métodos de aserción)
  • TerminatesProgramAttribute (por métodos que terminan flujo de control)
  • CanBeNullAttribute (para valores que pueden ser nula)
  • NotNullAttribute (por valores que no puede ser nulo)
+0

Puede obtener las Anotaciones de ReSharper de NuGet : https://www.nuget.org/packages/JetBrains.Annotations/ – aboy021

+3

Pero las anotaciones de resharper son solo un comentario legible para el reafilado ... no se verifican en el tiempo de ejecución – Revious

3

Como se señaló por Anton Gogolev, los atributos pueden ser creados usando PostSharp. (Tenga en cuenta que CodeContract está utilizando método estático llama dentro del cuerpo del método)

ACTUALIZACIÓN Feb 2013: nueva versión 3.0 de PostSharp (actualmente en beta) apoyará Validating parameters, fields and properties

1) El artículo tiene validate-parameters-using-attributes implementación de

clase pública NotEmpty: ParameterAttribute

clase pública NotNull: ParameterAttribute

[AttributeUsage (AttributeTargets.Parameter)]

ParameterAttribute clase abstracta pública: Atributo

{

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

}

También requiere un atributo de método con un aspecto del método límite para procesar los atributos de parámetro.

2) En el comentario al artículo hay enlaces a very similar implementation para no nulo/NonEmpty

[para volver: no nulo] pública SomeObject SomeMethod ([no nulo] otroObjeto param1)

El el código fuente se encuentra en google code Torch/DesignByContract

3) otro ejemplo más complicado se describe en http://badecho.com/2011/11/validating-method-parameters-with-postsharp/

6

Estas anotaciones son para ReSharper, y se copian del espacio de nombres JetBrains.Annotations. Un marco puede ponerlos en su propio espacio de nombres, sin embargo, ReSharper NO recogerá estas anotaciones automáticamente; necesita decirle a ReSharper que use el espacio de nombres personalizado en el cuadro de diálogo de opciones. Una vez que haya seleccionado el nuevo espacio de nombres, el análisis de ReSharper recogerá los atributos y le dará destacados y advertencias.

Cuestiones relacionadas