2009-06-10 9 views
9

私は本当に属性を理解していません。私は書籍のすべての種類の&それらを読んだが、私はそれを得ることはありません。dotnet/.NETでカスタム属性を実装する最適な方法は何ですか?

私はそれらを理解していないので、それらを効果的に使用する方法もわかりません。

1)属性が&のものであるかどうかの良い定義を教えてください。

2)C#でカスタム属性を作成して消費する方法の良いコード例を教えてもらえますか?

答えて

9

あなたは、リフレクションを使用して歩き回る一連のプロパティを持つクラスがあるとします。文字列であるものは、一定量を超えていないことを確認するために検証する必要があります。

あなたは、デフォルトの整数のコンストラクタと整数プロパティ/フィールドで、textLength属性を作成することができます。次に、クラスの各文字列プロパティーで属性を読み取り、属性値の長さを属性で指定された数と比較できます。

コード:

public class TextLengthAttribute : Attribute 
{ 
    private int length; 
    public int Length { get { retrun length; } set { length = value; } } 

    public TextLengthAttribute(int num) { this.length = num ; } 
} 

public class MyClass 
{ 

    [TextLength(10)] 
    public string Property1; 
    [TextLength(20)] 
    public string Property2; 
} 

public class ClassReader 
{ 
    public static void Main() 
    { 
      MyClass example = MyClass.GetTestData(); 

      PropertyInfo[] props = typeof(MyClass).GetProperties(); 
      foreach (PropertyInfo prop in props) 
      { 
       if (prop.ValueType == typeof(String) 
       { 
        TextLengthAttribute[] atts = 
         (TextLengthAttribute)[]prop.GetCustomAttributes(
          typeof(TextLengthAttribute), false); 
        if (prop.GetValue(example, null).ToString().Length > 
         atts[0].Length) 
         throw new Exception(prop.name + " was too long"); 
       } 
      } 
    } 
} 

注:テストされていない

2

log4PostSharp。彼らは属性を使用してAOP動作を導入します。

それは、このような性質、で使用されていた私は

[AttributeUsage(AttributeTargets.Property)] 
public sealed class UnitAttribute : Attribute 
{ 
    public UnitAttribute(Unit unit) 
    { 
    Unit = unit; 
    } 

    public Unit Unit { get; private set; } 
} 

(...秒のような、メートル、)プロパティに単位を与えるために、一度使用される属性です:

[Unit(Unit.Meter)] 
public float Distance { get; set; } 

あなたは後で属性を取得してGUIに表示することができます。

11

私はあなたの例を与えることができるが、それはこの素晴らしい記事と比較して見劣りします:

Defining and Using Custom Attribute Classes in C#

複雑、コンポーネントスタイル 開発を企業が現代のソフトウェア開発者の が必要と出て期待していること は従来の設計手法よりも柔軟性が高く設計されています。 Microsoftの.NET Frameworkは、 属性を広範に使用して、 の機能を追加し、 という「宣言型」プログラミングと呼ばれるものを提供します。 属性は、 機能の疎結合を促進するため、 ソフトウェアシステムの柔軟性を向上させます。 独自のカスタム属性クラス を作成してから の属性クラスを使用することができますので、 独自の属性の結合力を緩和した を利用できます。

2

属性は、任意のメンバー(フィールド、クラスなど)に関するメタデータを提供するために使用されます。

Attributeから継承して作成し、 Attribute.GetCustomAttributeメソッドを使用して消費することができます。

デフォルトの属性の例は、認証されたユーザーのみが特定のリソースにアクセスできるようにするPrincipalPermissionAttributeです。例:この例では

[PrincipalPermission (SecurityAction.Demand, Role="Supervisor")] 
public class DoTheThingPage : Page 
{ 
    //// 
} 

、我々は唯一の「スーパーバイザーの役割に属している認証されたユーザーが見ることができるASP.NETページを持っています。

(この属性は自動的にASP.NETのセキュリティサブシステムによって読み取られる)

はまた、クラス名の「属性」の部分が使用されていなかった、それは.NET内条約のことに注意してください。

3

我々は、特定のソート順でドロップダウンに列挙値を表示する必要があります。カスタム属性を使用して実装しました。

[AttributeUsage(AttributeTargets.Enum | AttributeTargets.Field, AllowMultiple = false)] 
public class EnumSortAttribute : Attribute 
{ 
    public int SortOrder; 
    public bool SortByDescription; 
} 

[EnumSort(SortByDescription=true)] 
public enum EnumSortByDescription 
{ 
    [Description("enO")] 
    One = 1, 
    [Description("2")] 
    Two = 2, 
    Three = 3, 
    [Description("rouF")] 
    Four = 4 
} 

public enum EnumCustomSortOrder 
{ 
    [EnumSort(SortOrder = 3)] 
    One = 1, 
    [EnumSort(SortOrder = 1)] 
    Two = 2, 
    [EnumSort(SortOrder = 2)] 
    Three = 3 
} 
1

属性は、クラス、構造体または一部のメンバーに追加情報(メタデータ)を追加するだけの方法です。このメタデータは、いくつかの決定を下すために他のコードによって取り出すことができます。

最も単純な例は、.NETのSerializableAttributeです。後でBinaryFormatterでクラスをシリアライズできることを示します。

ここ別の例だ - 私たちは、彼らがいずれかの可変フィールドを持ち、マルチスレッド操作に対してOKですしていないことを示すためにImmutableAttributeと我々のコードにいくつかのクラスをマークすることができます:私たちは、その後

[Immutable] 
public sealed class ProcessingMessage 
{ 
    //... some code that should be thread-safe 

} 

ユニットテストを作成して、その属性を持つすべてのクラスを見つけて確実に取得することができます。they are immutable indeed

[Test] 
public void Immutable_Types_Should_Be_Immutable() 
{ 
    var decorated = GlobalSetup.Types 
    .Where(t => t.Has<ImmutableAttribute>()); 

    foreach (var type in decorated) 
    { 
    var count = type.GetAllFields().Count(f => !f.IsInitOnly && !f.IsStatic); 
    Assert.AreEqual(0, count, "Type {0} should be immutable", type); 
    } 
} 
関連する問題