2009-04-27 6 views
38

Voglio consentire ai programmatori e al sottoscritto di sapere che un metodo non desidera null e se si invia comunque null ad esso, il risultato non sarà carino.C#: Come implementare e utilizzare un attributo NotNull e CanBeNull

C'è uno NotNullAttribute e uno CanBeNullAttribute in Lokad Shared Libraries, nello spazio dei nomi Lokad.Quality.

Ma come funziona? Ho guardato il codice sorgente di questi due attributi, e sembra che questo:

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

Due classi vuote che ereditano da Attribute. Come vengono utilizzati? Devi cercare la documentazione xml e sapere che è lì? Perché ho provato a creare la mia copia dell'attributo e ad usare la versione di Lokad, ma quando ho provato a inviare un null direttamente, non ho ricevuto alcun messaggio. Né da ReSharper né da VS. Quale mi aspettavo in realtà. Ma come vengono utilizzati? Posso in qualche modo creare VS avvisi per me se provo a inviare qualcosa che è nullo lì? O è solo usato in qualche tipo di framework di test? O?

+1

Per commentare il caso specifico, questi attributi non fanno nulla e sono solo "documentazione". Le altre risposte danno buone alternative, però. – Sander

+3

'Nullable' è un nome migliore per' CanBeNull', solo dicendo :) –

risposta

46

Nel medio termine, "contratti di codice" (in 4.0) sarà una risposta migliore a questo. Sono disponibili ora (con le licenze academic o commercial), ma saranno più integrati in VS2010. Questo può fornire sia l'analisi statica che il supporto al runtime.

(edit) Esempio:

Contract.RequiresAlways(x != null); 

semplice ... il motore contratti codice funziona a livello di IL, quindi è in grado di analizzare che e gettare le avvertenze/errori di chiamare il codice durante la compilazione, o per lo runtime. Per la compatibilità all'indietro, se il codice di convalida si è già esistente, si può solo dire che dove la sanità mentale controllo estremità, e lo farà il resto:

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

Sembrava molto semplice! Funzionerà anche in VS 2008? Cosa intendi per "più integrato"? – Svish

+0

Sì; i collegamenti che ho postato erano per la variante VS2008. Con "più integrato", intendo quello AFAIK, è integrato nell'IDE e nel runtime, piuttosto che essere un componente aggiuntivo separato. Non ho controllato (anzi, non posso) - ma questo * potrebbe * probabilmente significa che funziona anche nella Express Edition (il componente aggiuntivo no). –

+0

Freddo. Hai già provato questo componente aggiuntivo? Facile da installare e da usare? È sicuro da usare in un ambiente di produzione? (Gli altri dipendenti mi uccideranno se lo aggiungo?: P) – Svish

18

Questo può essere fatto sia con AOP, per cui un Consigli verifica a run-time se un parametro del metodo è nullo e se sono consentiti i valori nulli. Vedere PostSharp e Spring.NET per AOP.

Per quanto riguarda ReSharper, vedi Annotated Framework:

Abbiamo analizzato una grande quota di .NET Framework, così come NUnit Framework, e annotato attraverso file XML esterni, utilizzando una serie di attributi personalizzati dai JetBrains.Annotazioni namespace, in particolare:

  • StringFormatMethodAttribute (per i metodi che prendono stringhe di formato come parametri)
  • InvokerParameterNameAttribute (per i metodi con argomenti letterali stringa che dovrebbe corrispondere a uno dei parametri del chiamante)
  • AssertionMethodAttribute (per i metodi di asserzione)
  • AssertionConditionAttribute (per i parametri di condizione di metodi rivendicazione)
  • TerminatesProgramAttribute (per i metodi che terminano flusso di controllo)
  • CanBeNullAttribute (per valori che possono essere nullo)
  • NotNullAttribute (per valori che non possono essere NULL)
+0

Puoi ottenere le annotazioni ReSharper da NuGet : https://www.nuget.org/packages/JetBrains.Annotations/ – aboy021

+3

Ma le annotazioni di resharper sono solo un commento leggibile per il resharper .. non vengono controllati in fase di runtime – Revious

3

Come indicato da Anton Gogolev, attributi possono essere creati usando PostSharp. (Si noti che CodeContract utilizza metodo statico chiama all'interno del corpo del metodo)

UPDATE Feb 2013: nuova versione 3.0 di PostSharp (attualmente in Beta) sosterrà Validating parameters, fields and properties

1) Articolo validate-parameters-using-attributes ha implementazione di

public class notempty: ParameterAttribute

public class NotNull: ParameterAttribute

[AttributeUsage (AttributeTargets.Parameter)]

public abstract class ParameterAttribute: Attribute

{

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

}

richiedeva anche un attributo metodo con un aspetto metodo confine per elaborare gli attributi parametro.

2) Nel commento a questo articolo ci sono collegamenti a very similar implementation per non Null/NonEmpty

[ritorno: non Null] pubblica SomeObject SomeMethod ([Null] AnotherObject param1)

Il il codice sorgente si trova in google code Torch/DesignByContract

3) un altro esempio più complicato è descritto in http://badecho.com/2011/11/validating-method-parameters-with-postsharp/

6

Queste annotazioni sono per ReSharper e vengono copiate dallo spazio dei nomi JetBrains.Annotations. Un framework può inserirli nel proprio spazio dei nomi, tuttavia, ReSharper NON raccoglierà automaticamente queste annotazioni - è necessario indicare a ReSharper di utilizzare lo spazio dei nomi personalizzato nella finestra di dialogo delle opzioni. Una volta selezionato il nuovo spazio dei nomi, l'analisi di ReSharper raccoglierà gli attributi e ti fornirà evidenziazioni e avvertenze.

Problemi correlati