メソッドがnull
を必要としないことをプログラマーと私に知らせたいです。とにかくnull
を送信しても、結果はきれいではありません。
Lokad Shared Libraries にはNotNullAttribute
とCanBeNullAttribute
があり、Lokad.Quality
名前空間。
しかし、それはどのように機能しますか?これら2つの属性のソースコードを調べたところ、次のようになっています。
[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
から継承する2つの空のクラス。それらはどのように使用されますか? xml-documentationを調べて、それがあることを知っている必要がありますか?原因私は属性の独自のコピーを作成し、Lokadバージョンを使用しようとしましたが、nullを直接送信しようとしても、メッセージが表示されませんでした。 ReSharperからもVSからも。実際に私はそれを期待していました。しかし、それらはどのように使用されますか? nullであるものを送信しようとすると、VSに警告を生成させることができますか?それとも、ある種のテストフレームワークで使用されているだけですか?それとも?
中期的には、「4.0での」「コードコントラクト」がこれに対するより良い答えになります。それらは現在利用可能です( academic または commercial ライセンスで)、VS2010でより統合されます。これにより、静的解析とランタイムサポートの両方を提供できます。
(編集)例:
Contract.RequiresAlways( x != null );
簡単なことです...コードコントラクトエンジンはILレベルで動作するため、ビルド中または実行時にコードを呼び出すことにより、それを分析し、警告/エラーをスローできます。後方互換性のために、既存の検証コードがある場合は、健全性チェックが終了する場所を伝えるだけで、残りは処理されます。
if ( x == null ) throw new ArgumentNullException("x");
Contract.EndContractBlock();
これは [〜#〜] aop [〜#〜] で行うことができます。これにより、実行時にメソッドパラメータがnullであるかどうか、nullが許可されるかどうかが検証されます。 AOPについては PostSharp および Spring.NET をご覧ください。
ReSharperについては、 注釈付きフレームワーク を参照してください。
私たちは、.NET FrameworkクラスライブラリとNUnit Frameworkの大部分を分析し、JetBrains.Annotations名前空間のカスタム属性のセットを使用して、外部XMLファイルを通じて注釈を付けました。
- StringFormatMethodAttribute(フォーマット文字列をパラメーターとして取るメソッドの場合)
- InvokerParameterNameAttribute(呼び出し元パラメーターの1つと一致する必要のある文字列リテラル引数を持つメソッドの場合)
- AssertionMethodAttribute(アサーションメソッド用)
- AssertionConditionAttribute(アサーションメソッドの条件パラメーター用)
- TerminatesProgramAttribute(制御フローを終了するメソッドの場合)
- CanBeNullAttribute(nullの可能性がある値の場合)
- NotNullAttribute(nullにできない値の場合)
これらの注釈はReSharper用であり、JetBrains.Annotations名前空間からコピーされます。フレームワークはそれらを独自の名前空間に置くことができますが、ReSharperはこれらの注釈を自動的に取得しません-オプションダイアログでカスタム名前空間を使用するようReSharperに指示する必要があります。新しい名前空間を選択すると、ReSharperの分析により属性が取得され、ハイライトと警告が表示されます。
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 parameter, object value);
}
また、パラメーター属性を処理するために、メソッド境界アスペクトを持つメソッド属性が必要でした。
2)記事へのコメントには、 非常に類似した実装 for NonNull/NonEmptyへのリンクがあります
[戻り値:NonNull] public SomeObject SomeMethod([NonNull] AnotherObject param1)
ソースコードは次の場所にあります google code Torch/DesignByContract
3)別のより複雑な例は、 http://badecho.com/2011/11/validating-method-parameters-with-postsharp/ で説明されています