CLR/C# コードでカスタム属性を使用したり、聞いたりしたクールなアプリケーションは何ですか? 標準属性の面白い使い方もOK!
編集: Java の注釈は CLR の属性と同じように見えるため、Java 注釈の使用も有効です。
CLR/C# コードでカスタム属性を使用したり、聞いたりしたクールなアプリケーションは何ですか? 標準属性の面白い使い方もOK!
編集: Java の注釈は CLR の属性と同じように見えるため、Java 注釈の使用も有効です。
[TypeDescriptionProvider]
これは、カスタムランタイムプロパティモデルを提供するために使用できます-完全に異なるプロパティ、またはおそらくより高速なプロパティそして、見過ごされがちないくつかのコアなもの:
[TypeForwardedTo]
-再構築せずにアセンブリ間でタイプを移動するために使用されます[PrincipalPermission]
-メンバーにセキュリティを自動的に適用するために使用されます厳密にはC#ではありませんが、生徒の課題をマークするためのJavaアノテーション(= C#属性)の興味深い使用法を見つけました。毎学期、生徒用のマーキングロボットをプログラムしていますが、1年生は何らかの理由で指示に正確に従えないようで、もちろんマーキングロボットが故障する原因になっています。だから私がやっていることは、彼らのコードを調べて、仕様を満たしていないすべてのメソッドを見つけて、それらを修正することです。次に、間違っていた各メソッドに注釈(=属性)を付けて、マーキングロボットにそれらをマークダウンするように指示しました。これはおそらく、これを行うための最も簡単で直接的な方法だと思います。
xUnitを調べて、期待される動作の単体テストをマークし、データをテストにフィードするために属性がどのように使用されるかを確認してください。属性は、MSTest や NUnit よりも意味のある方法で使用されます。
Samples\TestMethodExtensibility\Example.csから:
public class Example
{
static int val;
[RepeatTest(5, Timeout=250)]
public void RepeatingTestMethod()
{
Thread.Sleep(100);
Assert.Equal(2, 2);
if (val == 0)
{
val++;
Thread.Sleep(1000);
}
}
}
test.xunit.extensions\DataTheories\TheoryAttributeTests.csから:
internal class TestMethodCommandClass
{
public static IEnumerable<object[]> EmptyData
{
get { return new object[0][]; }
}
public static IEnumerable<object[]> NullData
{
get { return null; }
}
public static IEnumerable<object[]> TheoryDataProperty
{
get { yield return new object[] { 2 }; }
}
[Theory, PropertyData("EmptyData")]
public void EmptyDataTheory() { }
[Theory, PropertyData("NullData")]
public void NullDataTheory() { }
[Theory, OleDbData(
@"Provider=Microsoft.Jet.OleDb.4.0; Data Source=DataTheories\UnitTestData.xls; Extended Properties=Excel 8.0",
"SELECT x, y, z FROM Data")]
public void TestViaOleDb(double x,
string y,
string z) { }
[Theory, PropertyData("TheoryDataProperty")]
public void TestViaProperty(int x) { }
[Theory, ExcelData(@"DataTheories\UnitTestData.xls", "SELECT x, y, z FROM Data")]
public void TestViaXls(double x,
string y,
string z) { }
}
詳細については、次を参照してください。
もちろん
属性の使用法はケント・ベックによって誇りにされています:
NUnit 2.0 は慣用的な設計の優れた例です。xUnit を移植するほとんどの人は、Smalltalk または Java バージョンを音訳するだけです。それは、最初に NUnit で行ったことでもあります。この新しいバージョンは NUnit であり、最初から C# で作成されていたはずです。
インターフェイスの実際の実装もデータとして提示したい場合があります。もちろん、これはReflectionを介して実行できますが、データとして公開するメンバーに特定の属性を使用することで、これを実行するために必要な作業をカプセル化できます。
その結果、実装を作成し、目的のメンバーを装飾して、それぞれの場合にReflectionコードを実行しなくても、コードとデータの両方を介してメンバーにクエリを実行できます。
属性を使用してクラスやメソッドを装飾し、リフレクションを使用して「属性付き」データを取得することがあります。
説明が少し難しいかもしれませんが、最後に属性を使用したのは、データベースにいくつかのエンティティがあるシステムです。
各エンティティにはある種の「コード」があり、各エンティティにはいくつかの解釈規則もあります。
私のプロジェクトには、データベースに存在するエンティティを表すエンティティ クラスが 1 つあり、一連の「ルール」クラスもあります。1 つのルール クラスには、特定のエンティティの解釈ロジックが含まれます。
特定の「ルール」(解釈) をエンティティの特定のインスタンスに「リンク」するために、カスタム属性を作成しました。
「Rule」クラスをこの属性で装飾し、この属性を使用して、これがルールであるエンティティを定義します。次に、DB からエンティティをロードするときに、正しいルールをそのエンティティに挿入します。
物事を明確にするための少しのコード:
public class MyEntity
{
public string Code
{
get;
private set;
}
public bool IsValidFor( ... )
{
IRule rule = RuleRegistry.GetRuleFor(this);
if( rule.IsValid() ) ...
}
}
[RuleAttrib("100")]
public class MyRule : IRule
{
public bool IsValid()
{
}
}
これはほんの一例ですが、ドリフトをキャッチできると思います。
MyRule クラスの RuleAttrib 属性は、これがコード「100」を持つ MyClass のインスタンスに適用されるべきルールであることを示しています。
RuleRegistry インスタンスは、(リフレクションを使用して) 現在のエンティティの正しい IRule を取得できます。
Postsharp と組み合わせて属性を使用した別の例は、「ロック」システムの実装です 。
カスタム Java アノテーションを使用して、主に開発者を対象とした特定のメソッドの特別な目的をマークします。
@ScriptingAPI
-- スクリプト API の一部として公開されているコードを示します (変更がパブリック API に影響を与える可能性があることを開発者に警告します)。@Transaction
-- トランザクションを開始/コミットしているデータベース ファサードのメソッドをマークします (このアノテーションを尊重する専用のトランザクション ハンドラ クラスがあります)。@NeedsAttentionToSupportFoo
-- 機能 Foo が近い将来対処する必要がある要件であることがわかっている場合、アノテーションを使用して、それをサポートするために触れる必要があるコードをマークします。 「ああ、Foo をサポートするにはこれを変更する必要があるだろう」と考え、注釈を付けます。Foo の実装が延期されるか、まったく行われない場合は、コード内に散らばっている時期尚早の最適化を元に戻すよりも、注釈を削除する方が簡単です。カスタム アノテーションのもう 1 つの良い使用例は、この Java スペシャリスト ニュースレターで取り上げられています。
Castle のActiveRecordは属性を使用します。データベースに永続化する必要があるクラスとフィールド (およびその方法) を示す属性で Model オブジェクトを装飾することにより、NHibernate のセットアップの複雑さの一部を隠します。検証コンポーネント内で属性を使用して、モデルベースの検証を ActiveRecord とMonorailスタックに追加することもできます。