Sdílet prostřednictvím


Zápis vlastních atributů

Chcete-li navrhnout vlastní atributy, nepotřebujete zvládnout mnoho nových konceptů. Pokud jste obeznámeni s objektově orientovaným programováním a víte, jak navrhovat třídy, máte už většinu potřebných znalostí. Vlastní atributy jsou v podstatě tradičními třídami, které jsou odvozeny přímo nebo nepřímo z System.Attribute. Stejně jako tradiční třídy, vlastní atributy obsahují metody, které slouží k ukládání a načítání dat.

Primární kroky, které je třeba provést pro správný návrh vlastních tříd atributů jsou tyto:

  • Použití AttributeUsageAttribute

  • Deklarování třídy atributu

  • Deklarování konstruktorů

  • Deklarace vlastností

V tomto oddíle je popsán každý z těchto kroků a oddíl končí příkladem vlastní atribut.

Použití AttributeUsageAttribute

Deklarace vlastního atributu začíná AttributeUsageAttribute, který definuje některé klíčové charakteristiky vaší třídy atributů. Například můžete určit, zda požadovaný atribut může být děděn jinými třídami, nebo určit, na které prvky lze atribut použít. Následující fragment kódu demonstruje použití AttributeUsageAttribute.

<AttributeUsage(AttributeTargets.All, Inherited := False, AllowMultiple := True)>
Public Class SomeClass
    Inherits Attribute
    '...
End Class
[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
[AttributeUsage(AttributeTargets::All, Inherited = false, AllowMultiple = true)]

System.AttributeUsageAttribute má tři členy, které jsou důležité pro vytvoření vlastních atributů: AttributeTargets, Inherited a AllowMultiple.

Člen AttributeTargets

V předchozím příkladu je zadán AttributeTargets.All, označující, že tento atribut lze použít pro všechny prvky programu. Alternativně můžete zadat AttributeTargets.Class, označující, že váš atribut lze použít pouze na třídu, nebo AttributeTargets.Method, označující, že váš atribut lze použít pouze pro metodu. Všechny prvky programu mohou být označeny pro popis vlastním atributem.

Můžete také předat mnohonásobné instance AttributeTargets. Následující fragment kódu určuje, že lze vlastní atribut použít na jakoukoli třídu nebo metodu.

<AttributeUsage(AttributeTargets.Class Or AttributeTargets.Method)>
Public Class SomeOtherClass
    Inherits Attribute
    '...
End Class
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
[AttributeUsage(AttributeTargets::Class | AttributeTargets::Method)]

Zděděná vlastnost

Vlastnost Inherited označuje, zda požadovaný atribut může být zděděn třídami, které jsou odvozeny od tříd, na které je použit požadovaný atribut. Tato vlastnost má buď označení true (výchozí) nebo označení false. Například v následujícím příkladu kódu MyAttribute má výchozí hodnotu Inheritedtrue, zatímco YourAttribute má hodnotu Inherited false.

' This defaults to Inherited = true.
Public Class MyAttribute
    Inherits Attribute
    '...
End Class

<AttributeUsage(AttributeTargets.Method, Inherited := False)>
Public Class YourAttribute
    Inherits Attribute
    '...
End Class
// This defaults to Inherited = true.
public class MyAttribute : Attribute
{
    //...
}

[AttributeUsage(AttributeTargets.Method, Inherited = false)]
public class YourAttribute : Attribute
{
    //...
}
// This defaults to Inherited = true.
public ref class MyAttribute : Attribute
{
    //...
};

[AttributeUsage(AttributeTargets::Method, Inherited = false)]
public ref class YourAttribute : Attribute
{
    //...
};

Dva atributy jsou poté použity na metodu v základní třídě MyClass.

Public Class MeClass
    <MyAttribute>
    <YourAttribute>
    Public Overridable Sub MyMethod()
        '...
    End Sub
End Class
public class MyClass
{
    [MyAttribute]
    [YourAttribute]
    public virtual void MyMethod()
    {
        //...
    }
}
public ref class MyClass
{
public:
    [MyAttribute]
    [YourAttribute]
    virtual void MyMethod()
    {
        //...
    }
};

Nakonec je třída YourClass zděděna ze základní třídy MyClass. Metoda MyMethod ukazuje MyAttribute, ale ne YourAttribute.

Public Class YourClass
    Inherits MeClass
    ' MyMethod will have MyAttribute but not YourAttribute.
    Public Overrides Sub MyMethod()
        '...
    End Sub

End Class
public class YourClass : MyClass
{
    // MyMethod will have MyAttribute but not YourAttribute.
    public override void MyMethod()
    {
        //...
    }

}
public ref class YourClass : MyClass
{
public:
    // MyMethod will have MyAttribute but not YourAttribute.
    virtual void MyMethod() override
    {
        //...
    }

};

Vlastnost AllowMultiple

Vlastnost AllowMultiple označuje, zda může existovat více instancí atributu v elementu. Pokud je nastaveno true mnohonásobné instance jsou povoleny. Pokud je nastaveno false (výchozí), je povolena pouze jedna instance.

V následujícím příkladu kódu má MyAttribute hodnotu proměnné AllowMultiple nastavenu na výchozí hodnotu false, zatímco YourAttribute má hodnotu true.

' This defaults to AllowMultiple = false.
Public Class MyAttribute
    Inherits Attribute
End Class

<AttributeUsage(AttributeTargets.Method, AllowMultiple := true)>
Public Class YourAttribute
    Inherits Attribute
End Class
//This defaults to AllowMultiple = false.
public class MyAttribute : Attribute
{
}

[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class YourAttribute : Attribute
{
}
//This defaults to AllowMultiple = false.
public ref class MyAttribute : Attribute
{
};

[AttributeUsage(AttributeTargets::Method, AllowMultiple = true)]
public ref class YourAttribute : Attribute
{
};

Při použití vícenásobných instancí těchto atributů, MyAttribute vytvoří chybu kompilátoru. Následující příklad kódu znázorňuje platné použití YourAttribute a neplatné použití MyAttribute.

Public Class MyClass
    ' This produces an error.
    ' Duplicates are not allowed.
    <MyAttribute>
    <MyAttribute>
    Public Sub MyMethod()
        '...
    End Sub

    ' This is valid.
    <YourAttribute>
    <YourAttribute>
    Public Sub YourMethod()
        '...
    End Sub
End Class
public class MyClass
{
    // This produces an error.
    // Duplicates are not allowed.
    [MyAttribute]
    [MyAttribute]
    public void MyMethod()
    {
        //...
    }

    // This is valid.
    [YourAttribute]
    [YourAttribute]
    public void YourMethod()
    {
        //...
    }
}
public ref class MyClass
{
public:
    // This produces an error.
    // Duplicates are not allowed.
    [MyAttribute]
    [MyAttribute]
    void MyMethod()
    {
        //...
    }

    // This is valid.
    [YourAttribute]
    [YourAttribute]
    void YourMethod()
    {
        //...
    }
};

Pokud obě vlastnosti AllowMultiple a Inherited jsou nastaveny na true, třída, která je zděděna z jiné třídy, může dědit atribut a mít další instance stejného atributu použité ve stejné podřízené třídě. Pokud je AllowMultiple nastavena na hodnotu false, hodnoty atributů v nadřazené třídě budou přepsány novými instancemi stejného atributu v podřízené třídě.

Deklarování třídy atributu

Po použití AttributeUsageAttribute, můžete začít definovat specifické požadovky na atribut. Deklarace třídy atributu je podobá jako deklarace tradiční třídy, jak je znázorněno v následujícím kódu.

<AttributeUsage(AttributeTargets.Method)>
Public Class MyAttribute
    Inherits Attribute
    ' . . .
End Class
[AttributeUsage(AttributeTargets.Method)]
public class MyAttribute : Attribute
{
    // . . .
}
[AttributeUsage(AttributeTargets::Method)]
public ref class MyAttribute : Attribute
{
    // . . .
};

Tato definice atributu ukazuje následující body:

  • Třídy atributu musí být deklarovány jako veřejné třídy.

  • Dle konvencí, končí název třídy atributu slovem Attribute. Toto není požadováno. Tato konvence se však doporučuje pro čitelnost. Když se použije atribut, zařazení slova Attribute je volitelné.

  • Všechny třídy atributu musí dědit přímo nebo nepřímo z System.Attribute.

  • V jazyce Microsoft Visual Basic, všechny vlastní třídy atributu musí mít atribut AttributeUsageAttribute.

Deklarování konstruktorů.

Atributy jsou inicializovány konstruktory stejným způsobem jako tradiční třídy. Následující fragment kódu ukazuje typický konstruktor atributu. Tento veřejný konstruktor přebírá parametr a nastaví jeho hodnotu na stejnou hodnotu jako je hodnota členské proměnné.

Public Sub New(myvalue As Boolean)
    Me.myvalue = myvalue
End Sub
public MyAttribute(bool myvalue)
{
    this.myvalue = myvalue;
}
MyAttribute(bool myvalue)
{
    this->myvalue = myvalue;
}

Můžete použít přetížení konstruktoru pro různé kombinace hodnot. Pokud také definujete property pro vaši vlastní třídu atributu, je možné použít kombinaci pozičních a pojmenovaných parametrů při inicializaci atributu. Obvykle definujete všechny požadované parametry jako poziční a všechny volitelné parametry jako pojmenované. Atribut v tomto případě nelze inicializovat bez povinného parametru. Všechny další parametry jsou volitelné. Všimněte si, že v jazyce Visual Basic konstruktory pro třídu atributu by neměly používat argument ParamArray.

Následující příklad kódu ukazuje jak atribut, který používá předchozí konstruktor lze aplikovat pomocí požadováného a volitelného parametru. Předpokládá se, že atribut má jednu požadovanou booleovskou hodnotu a jednu volitelnou vlastnost typu řetězec.

' One required (positional) and one optional (named) parameter are applied.
<MyAttribute(false, OptionalParameter := "optional data")>
Public Class SomeClass
    '...
End Class

' One required (positional) parameter is applied.
<MyAttribute(false)>
Public Class SomeOtherClass
    '...
End Class
// One required (positional) and one optional (named) parameter are applied.
[MyAttribute(false, OptionalParameter = "optional data")]
public class SomeClass
{
    //...
}
// One required (positional) parameter is applied.
[MyAttribute(false)]
public class SomeOtherClass
{
    //...
}
// One required (positional) and one optional (named) parameter are applied.
[MyAttribute(false, OptionalParameter = "optional data")]
public ref class SomeClass
{
    //...
};
// One required (positional) parameter is applied.
[MyAttribute(false)]
public ref class SomeOtherClass
{
    //...
};

Deklarace vlastností

Pokud chcete definovat pojmenovaný parametr nebo poskytnout snadný způsob pro vrácení hodnot uložených ve vašem atributu, deklarujte property. Vlastnosti atributu by měly být deklarovány jako veřejné entity s popisem datového typu, který bude vrácen. Definujte proměnnou, která bude obsahovat hodnotu vaší vlastnosti a přidruží ji k metodám get a set. Následující příklad kódu demonstruje, jak implementovat jednoduché vlastnosti ve vašem atributu.

Public Property MyProperty As Boolean
    Get
       Return Me.myvalue
    End Get
    Set
        Me.myvalue = Value
    End Set
End Property
public bool MyProperty
{
    get {return this.myvalue;}
    set {this.myvalue = value;}
}
property bool MyProperty
{
    bool get() {return this->myvalue;}
    void set(bool value) {this->myvalue = value;}
}

Příklad vlastního atributu

Tato část zahrnuje předchozí informace a ukazuje, jak navrhnout jednoduché atributy, které dokumentují informace o autorovi oddílu kódu. Atribut v tomto příkladu ukládá název a úroveň programátora a informaci, zda byl kód revidován. Používá tři soukromé proměnné pro uložení hodnot, které mají být uloženy. Každá proměnná je reprezentována veřejnou vlastností, která získá a nastaví hodnoty. Nakonec je definován konstruktor s dvěma požadovanými parametry.

<AttributeUsage(AttributeTargets.All)>
Public Class DeveloperAttribute
    Inherits Attribute
    ' Private fields.
    Private myname As String
    Private mylevel As String
    Private myreviewed As Boolean

    ' This constructor defines two required parameters: name and level.

    Public Sub New(name As String, level As String)
        Me.myname = name
        Me.mylevel = level
        Me.myreviewed = False
    End Sub

    ' Define Name property.
    ' This is a read-only attribute.

    Public Overridable ReadOnly Property Name() As String
        Get
            Return myname
        End Get
    End Property

    ' Define Level property.
    ' This is a read-only attribute.

    Public Overridable ReadOnly Property Level() As String
        Get
            Return mylevel
        End Get
    End Property

    ' Define Reviewed property.
    ' This is a read/write attribute.

    Public Overridable Property Reviewed() As Boolean
        Get
            Return myreviewed
        End Get
        Set
            myreviewed = value
        End Set
    End Property
End Class
[AttributeUsage(AttributeTargets.All)]
public class DeveloperAttribute : Attribute
{
    // Private fields.
    private string name;
    private string level;
    private bool reviewed;

    // This constructor defines two required parameters: name and level.

    public DeveloperAttribute(string name, string level)
    {
        this.name = name;
        this.level = level;
        this.reviewed = false;
    }

    // Define Name property.
    // This is a read-only attribute.

    public virtual string Name
    {
        get {return name;}
    }

    // Define Level property.
    // This is a read-only attribute.

    public virtual string Level
    {
        get {return level;}
    }

    // Define Reviewed property.
    // This is a read/write attribute.

    public virtual bool Reviewed
    {
        get {return reviewed;}
        set {reviewed = value;}
    }
}
[AttributeUsage(AttributeTargets::All)]
public ref class DeveloperAttribute : Attribute
{
    // Private fields.
private:
    String^ name;
    String^ level;
    bool reviewed;

public:
    // This constructor defines two required parameters: name and level.

    DeveloperAttribute(String^ name, String^ level)
    {
        this->name = name;
        this->level = level;
        this->reviewed = false;
    }

    // Define Name property.
    // This is a read-only attribute.

    virtual property String^ Name
    {
        String^ get() {return name;}
    }

    // Define Level property.
    // This is a read-only attribute.

    virtual property String^ Level
    {
        String^ get() {return level;}
    }

    // Define Reviewed property.
    // This is a read/write attribute.

    virtual property bool Reviewed
    {
        bool get() {return reviewed;}
        void set(bool value) {reviewed = value;}
    }
};

Můžete použít tento atribut pomocí úplného názvu, DeveloperAttribute, nebo pomocí zkráceného názvu Developer, jedním z následujících způsobů.

<Developer("Joan Smith", "1")>

-or-

<Developer("Joan Smith", "1", Reviewed := true)>
[Developer("Joan Smith", "1")]

-or-

[Developer("Joan Smith", "1", Reviewed = true)]
[Developer("Joan Smith", "1")]

-or-

[Developer("Joan Smith", "1", Reviewed = true)]

První příklad ukazuje atribut pouze s požadovanými pojmenovanými parametry, zatímco druhý příklad ukazuje atribut s požadovanými a volitelnými parametry.

Viz také

Odkaz

System.Attribute

AttributeUsageAttribute

Koncepty

Rozšíření metadat pomocí atributů