Egyéni attribútumok írása

Az egyéni attribútumok tervezéséhez nem kell sok új fogalmat elsajátítania. Ha ismeri az objektumorientált programozást, és tudja, hogyan kell osztályokat tervezni, már rendelkezik a szükséges ismeretek többségével. Az egyéni attribútumok olyan hagyományos osztályok, amelyek közvetlenül vagy közvetve származnak az System.Attribute osztályból. A hagyományos osztályokhoz hasonlóan az egyéni attribútumok is olyan metódusokat tartalmaznak, amelyek adatokat tárolnak és kérnek le.

Az egyéni attribútumosztályok megfelelő tervezésének elsődleges lépései a következők:

Ez a szakasz ezeket a lépéseket ismerteti, és egy egyéni attribútum-példával zárul.

Az AttributeUsageAttribute alkalmazása

Az egyéni attribútumdeklaráció az System.AttributeUsageAttribute attribútummal kezdődik, amely meghatározza az attribútumosztály néhány fő jellemzőjét. Megadhatja például, hogy az attribútumot más osztályok örökölhetik-e, vagy hogy az attribútum mely elemekre alkalmazható. Az alábbi kódrészlet bemutatja, hogyan használhatja a AttributeUsageAttributekövetkezőt:

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

A AttributeUsageAttribute három tag fontos az egyéni attribútumok létrehozásához: AttributeTargets, Inherited és AllowMultiple.

AttributeTargets-tag

Az előző példában meg van adva, AttributeTargets.All ami azt jelzi, hogy ez az attribútum az összes programelemre alkalmazható. Másik lehetőségként megadhatja AttributeTargets.Class, hogy az attribútum csak egy osztályra alkalmazható legyen, vagy AttributeTargets.Methodazt jelzi, hogy az attribútum csak egy metódusra alkalmazható. Minden programelemet megjelölhet leírásra egy egyéni attribútummal, így.

Több AttributeTargets értéket is átadhat. A következő kódtöredék azt határozza meg, hogy egy egyéni attribútum bármely osztályra vagy metódusra alkalmazható legyen:

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

Örökölt tulajdonság

A AttributeUsageAttribute.Inherited tulajdonság azt jelzi, hogy az attribútum örökölhető-e azoknak az osztályoknak az alapján, amelyekre az attribútumot alkalmazza. Ez a tulajdonság egy (alapértelmezett) vagy false jelölőt használ true . Az alábbi példában az alapértelmezett érték a truekövetkező, MyAttribute míg YourAttributeInherited az értéke:falseInherited

// This defaults to Inherited = true.
public ref class MyAttribute : Attribute
{
    //...
};

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

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

<AttributeUsage(AttributeTargets.Method, Inherited:=False)>
Public Class YourAttribute
    Inherits Attribute
    '...
End Class

A rendszer ezután alkalmazza a két attribútumot az alaposztály MyClassegyik metódusára:

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

Végül az osztály YourClass az alaposztálytól MyClassöröklődik. A metódus a következőt MyMethod mutatja, MyAttribute de nem YourAttribute:

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

};
public class YourClass : MyClass
{
    // MyMethod will have MyAttribute but not YourAttribute.
    public override void MyMethod()
    {
        //...
    }
}
Public Class YourClass
    Inherits MeClass
    ' MyMethod will have MyAttribute but not YourAttribute.
    Public Overrides Sub MyMethod()
        '...
    End Sub

End Class

AllowMultiple tulajdonság

A AttributeUsageAttribute.AllowMultiple tulajdonság azt jelzi, hogy az attribútum több példánya létezhet-e egy elemen. Ha be van trueállítva, több példány is engedélyezett. Ha az alapértelmezett értékre van false állítva, csak egy példány engedélyezett.

Az alábbi példában az alapértelmezett érték a falsekövetkező, MyAttribute míg YourAttribute az értéketrue:AllowMultiple

//This defaults to AllowMultiple = false.
public ref class MyAttribute : Attribute
{
};

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

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

<AttributeUsage(AttributeTargets.Method, AllowMultiple:=true)>
Public Class YourAttribute
    Inherits Attribute
End Class

Ezen attribútumok több példányának alkalmazásakor MyAttribute fordítóhiba lép fel. Az alábbi példakód a következők érvényes használatát YourAttribute és érvénytelen használatát MyAttributemutatja be:

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

    // This is valid.
    [YourAttribute]
    [YourAttribute]
    void YourMethod()
    {
        //...
    }
};
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 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

Ha a AllowMultiple tulajdonság és a Inherited tulajdonság is értékre truevan állítva, egy másik osztálytól öröklő osztály örökölhet egy attribútumot, és ugyanazon attribútum egy másik példányát is alkalmazhatja ugyanabban a gyermekosztályban. Ha AllowMultiple be van állítva false, a szülőosztályban lévő attribútumok értékeit felülírják a gyermekosztály azonos attribútumának új példányai.

Az attribútumosztály deklarálása

Az alkalmazás AttributeUsageAttributeután kezdje el meghatározni az attribútum jellemzőit. Az attribútumosztály deklarációja hasonlít egy hagyományos osztály deklarációjára, ahogy azt az alábbi kód is mutatja:

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

Ez az attribútumdefiníció a következő pontokat mutatja be:

  • Az attribútumosztályokat nyilvános osztályként kell deklarálni.

  • Konvenció szerint az attribútumosztály neve az Attribútum szóval végződik. Bár nem kötelező, ez a konvenció ajánlott az olvashatóság érdekében. Az attribútum alkalmazásakor az Attribútum szó nem kötelező.

  • Minden attribútumosztálynak közvetlenül vagy közvetve kell örökölnie az System.Attribute osztálytól.

  • A Microsoft Visual Basicben minden egyéni attribútumosztálynak rendelkeznie kell az System.AttributeUsageAttribute attribútummal.

Konstruktorok deklarálása

A hagyományos osztályokhoz hasonlóan az attribútumok konstruktorokkal inicializálódnak. Az alábbi kódrészlet egy tipikus attribútumkonstruktort mutat be. Ez a nyilvános konstruktor egy paramétert vesz fel, és beállít egy tagváltozót, amely megegyezik az értékével.

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

A konstruktort túlterhelheti az értékek különböző kombinációinak elhelyezésére. Ha az egyéni attribútumosztályhoz is definiál egy tulajdonságot , az attribútum inicializálásakor névvel ellátott és pozícióparaméterek kombinációját is használhatja. Általában az összes szükséges paramétert pozícióként, az összes választható paramétert pedig nevesítettként definiálja. Ebben az esetben az attribútum nem inicializálható a szükséges paraméter nélkül. Az összes többi paraméter megadása nem kötelező.

Feljegyzés

A Visual Basicben az attribútumosztály konstruktorainak nem szabad argumentumot ParamArray használniuk.

Az alábbi példakód bemutatja, hogyan alkalmazható az előző konstruktort használó attribútum opcionális és kötelező paraméterekkel. Feltételezi, hogy az attribútum egy kötelező logikai értékkel és egy opcionális sztringtulajdonságokkal rendelkezik.

// 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
{
    //...
};
// 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 Class SomeClass
    '...
End Class

' One required (positional) parameter is applied.
<MyAttribute(false)>
Public Class SomeOtherClass
    '...
End Class

Tulajdonságok deklarálása

Ha elnevezett paramétert szeretne definiálni, vagy egyszerű módot szeretne biztosítani az attribútum által tárolt értékek visszaadására, deklaráljon egy tulajdonságot. Az attribútumtulajdonságokat nyilvános entitásként kell deklarálni a visszaadandó adattípus leírásával. Adja meg azt a változót, amely a tulajdonság értékét fogja tárolni, és társítja azt a metódusokkal és set metódusokkalget. Az alábbi példakód bemutatja, hogyan implementálhat egy tulajdonságot az attribútumban:

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

Példa egyéni attribútumra

Ez a szakasz tartalmazza a korábbi információkat, és bemutatja, hogyan tervezhet meg egy attribútumot, amely a kód egy szakaszának szerzőjének adatait dokumentálja. A példában szereplő attribútum tárolja a programozó nevét és szintjét, valamint azt, hogy a kód felül lett-e vizsgálva. Három privát változót használ a mentéshez használt tényleges értékek tárolásához. Minden változót egy olyan nyilvános tulajdonság jelöl, amely lekéri és beállítja az értékeket. Végül a konstruktor két szükséges paraméterrel van definiálva:

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

Ezt az attribútumot a teljes név vagy DeveloperAttributea rövidített név Developerhasználatával alkalmazhatja az alábbi módok egyikével:

[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)>

Az első példa csak a szükséges elnevezett paraméterekkel alkalmazott attribútumot mutatja be. A második példa a szükséges és az opcionális paraméterekkel együtt alkalmazott attribútumot mutatja be.

Lásd még