Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
23.1 Általános
A C#-nyelv nagy része lehetővé teszi, hogy a programozó deklaratív információkat adjon meg a programban meghatározott entitásokról. Egy osztályban például egy metódus akadálymentességét úgy adhatja meg, hogy az method_modifiers public, protected, internalés private.
A C# lehetővé teszi a programozók számára, hogy új deklaratív információkat, úgynevezett attribútumokattaláljanak ki. A programozók ezután attribútumokat csatolhatnak a különböző programentitásokhoz, és lekérhetik az attribútuminformációkat egy futásidejű környezetben.
Megjegyzés: Előfordulhat például, hogy egy keretrendszer meghatároz egy
HelpAttributeattribútumot, amely elhelyezhető bizonyos programelemeken (például osztályokon és metódusokon), hogy megfeleltetést biztosítson ezekből a programelemekből a dokumentációjukba. végjegyzet
Az attribútumokat az attribútumosztályok deklarációja (23.2. §) határozza meg, amelyek helymeghatározó és elnevezett paraméterekkel rendelkezhetnek (23.2.3. §). Az attribútumok attribútumspecifikációk (23.3.§) használatával kapcsolódnak egy C#-program entitásaihoz, és futtatáskor attribútumpéldányokként kérhetők le (23.4. §).
23.2 Attribútumosztályok
23.2.1 Általános
Az absztrakt osztályból System.Attributeszármazó osztály – akár közvetlenül, akár közvetve – attribútumosztály. Az attribútumosztály deklarálása egy új típusú attribútumot határoz meg, amely programentitásokon helyezhető el. Konvenció szerint az attribútumosztályok neve a következő utótaggal Attributevan elnevezve: . Az attribútumok használata magában foglalhatja vagy kihagyhatja ezt az utótagot.
Az általános osztály deklarációja nem használható System.Attribute közvetlen vagy közvetett alaposztályként.
Példa:
public class B : Attribute {} public class C<T> : B {} // Error – generic cannot be an attributezáró példa
23.2.2 Attribútumhasználat
Az attribútum AttributeUsage (23.5.2. §) az attribútumosztályok felhasználási módjának leírására szolgál.
AttributeUsage rendelkezik egy pozícióparaméterrel (23.2.3. §), amely lehetővé teszi, hogy az attribútumosztály meghatározza azokat a programentitások típusait, amelyeken használható.
Példa: Az alábbi példa egy attribútumosztályt
SimpleAttributehatároz meg, amely csak class_declaration s és interface_declarations-n helyezhető el, és azSimpleattribútum több használatát is megjeleníti.[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface)] public class SimpleAttribute : Attribute { ... } [Simple] class Class1 {...} [Simple] interface Interface1 {...}Bár ez az attribútum a névvel
SimpleAttributevan definiálva , az attribútum használatakor előfordulhat, hogy azAttributeutótag hiányzik, ami a rövid nevetSimpleeredményezi. Így a fenti példa szemantikailag egyenértékű a következő[SimpleAttribute] class Class1 {...} [SimpleAttribute] interface Interface1 {...}záró példa
AttributeUsage nevű paramétere (23.2.3. §), AllowMultipleamely azt jelzi, hogy az attribútum egy adott entitáshoz többször is megadható-e. Ha AllowMultiple egy attribútumosztály értéke igaz, akkor az attribútumosztály egy többfelhasználós attribútumosztály, amely egy entitáson többször is megadható. Ha AllowMultiple egy attribútumosztály értéke hamis vagy nincs meghatározva, akkor az attribútumosztály egy egyszer használatos attribútumosztály, és legfeljebb egyszer adható meg egy entitáson.
Példa: Az alábbi példa egy elnevezett
AuthorAttributetöbbfelhasználós attribútumosztályt határoz meg, és egy osztálydeklarációt jelenít meg azAuthorattribútum két használatával:[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] public class AuthorAttribute : Attribute { public string Name { get; } public AuthorAttribute(string name) => Name = name; } [Author("Brian Kernighan"), Author("Dennis Ritchie")] class Class1 { ... }záró példa
AttributeUsage van egy másik elnevezett paramétere (23.2.3. §), Inheritedamely azt jelzi, hogy az attribútumot az alaposztályban megadottak is öröklik-e az adott alaposztályból származó osztályok. Ha Inherited egy attribútumosztály értéke igaz, akkor az attribútum öröklődik. Ha Inherited egy attribútumosztály hamis, akkor az attribútum nem öröklődik. Ha nincs meghatározva, az alapértelmezett értéke igaz.
Olyan attribútumosztály X , amelyhez AttributeUsage nincs attribútum csatolva, mint a
class X : Attribute { ... }
egyenértékű a következő értékével:
[AttributeUsage(
AttributeTargets.All,
AllowMultiple = false,
Inherited = true)
]
class X : Attribute { ... }
23.2.3 Pozíció- és elnevezett paraméterek
Az attribútumosztályok s pozícióparamétertés elnevezett paraméterttartalmazhatnak. Az attribútumosztály minden nyilvános példány-konstruktora az adott attribútumosztályhoz tartozó pozícióparaméterek érvényes sorozatát határozza meg. Az attribútumosztály minden nem statikus nyilvános olvasási-írási mezője és tulajdonsága egy elnevezett paramétert határoz meg az attribútumosztályhoz. Ahhoz, hogy egy tulajdonság megnevezett paramétert határozzon meg, az adott tulajdonságnak nyilvános lekéréses tartozékot és nyilvános tartozékot is tartalmaznia kell.
Példa: Az alábbi példa egy egy pozícióparamétert
HelpAttributeés egy elnevezett paraméterturltartalmazó attribútumosztálytTopichatároz meg. Bár nem statikus és nyilvános, a tulajdonságUrlnem definiál elnevezett paramétert, mivel nem írás-olvasás. Az attribútum két felhasználási módja is látható:[AttributeUsage(AttributeTargets.Class)] public class HelpAttribute : Attribute { public HelpAttribute(string url) // url is a positional parameter { ... } // Topic is a named parameter public string Topic { get; set; } public string Url { get; } } [Help("http://www.mycompany.com/xxx/Class1.htm")] class Class1 { } [Help("http://www.mycompany.com/xxx/Misc.htm", Topic ="Class2")] class Class2 { }záró példa
23.2.4 Attribútumparaméter-típusok
Az attribútumosztály helymeghatározó és elnevezett paramétereinek típusai az s attribútumparaméter-típusrakorlátozódnak, amelyek a következők:
- Az alábbi típusok egyike: , , , , ,
bool,bytechar,double,floatint, ,long, .sbyteshortstringuintulongushort - A típus
object. - A típus
System.Type. - Enumerálási típusok.
- A fenti típusok egydimenziós tömbjei.
- Egy konstruktor argumentum vagy nyilvános mező, amely nem rendelkezik ilyen típussal, nem használható pozíció- vagy elnevezett paraméterként az attribútum specifikációjában.
23.3 Attribútum specifikációja
A korábban definiált attribútumokat attribútumspecifikációnak nevezzük. Az attribútum egy programentitáshoz megadott további deklaratív információ. Az attribútumok a globális hatókörben (a szerelvény vagy modul attribútumainak megadásához) és type_declarations (14.7.§), class_member_declarations (15.3. §), interface_member_declarations (19. §) esetén adhatók meg. 4), struct_member_declarations (§16.3), enum_member_declarations (§20.2), accessor_declarations (§15.7.3), event_accessor_declarations (§15.8), parameter_listelemeit (15.6.2. §) és type_parameter_listelemeit (15.2.3. §).
Az attribútumok az s attribútumszakaszbanvannak megadva. Az attribútumszakaszok szögletes zárójelekből állnak, amelyek egy vagy több attribútum vesszővel tagolt listáját veszik körül. Az attribútumok ilyen listában való megadásának sorrendje, valamint az a sorrend, amelyben az adott programentitásához csatolt szakaszok rendezve vannak, nem jelentős. Az attribútum-specifikációk például egyenértékűek[A][B][B][A][A, B][B, A].
global_attributes
: global_attribute_section+
;
global_attribute_section
: '[' global_attribute_target_specifier attribute_list ']'
;
global_attribute_target_specifier
: global_attribute_target ':'
;
global_attribute_target
: identifier
;
attributes
: attribute_section+
;
attribute_section
: '[' attribute_target_specifier? attribute_list ']'
;
attribute_target_specifier
: attribute_target ':'
;
attribute_target
: identifier
| keyword
;
attribute_list
: attribute (',' attribute)* ','?
;
attribute
: attribute_name attribute_arguments?
;
attribute_name
: type_name
;
attribute_arguments
: '(' ')'
| '(' positional_argument_list (',' named_argument_list)? ')'
| '(' named_argument_list ')'
;
positional_argument_list
: positional_argument (',' positional_argument)*
;
positional_argument
: argument_name? attribute_argument_expression
;
named_argument_list
: named_argument (',' named_argument)*
;
named_argument
: identifier '=' attribute_argument_expression
;
attribute_argument_expression
: non_assignment_expression
;
Az éles global_attribute_target és az alábbi szövegben az azonosítónak a assemblymodule6.4.3. Az éles attribute_target és az alábbi szövegben az azonosítónak olyan helyesírással kell rendelkeznie, amely nem egyenlő assembly vagy module– az egyenlőség fenti definícióját használva .
Az attribútumok attribute_name és a pozíció- és elnevezett argumentumok választható listájából állnak. A pozícióargumentumok (ha vannak ilyenek) megelőzik az elnevezett argumentumokat. A pozícióargumentumok egy attribute_argument_expression, egy elnevezett argumentum egy névből, majd egy egyenlőségjelből állnak, majd egy attribute_argument_expression, amelyet együtt ugyanazok a szabályok korlátoznak, mint az egyszerű hozzárendelés. Az elnevezett argumentumok sorrendje nem jelentős.
Megjegyzés: Az egyszerűség kedvéért a záró vesszők global_attribute_section és attribute_section is megengedettek, ahogyan az array_initializer megengedett (17.7. §). végjegyzet
A attribute_name egy attribútumosztályt azonosít.
Ha egy attribútum globális szinten van elhelyezve, global_attribute_target_specifier kell megadni. Ha a global_attribute_target egyenlő:
-
assembly— a cél a tárolószerelvény -
module— a cél az azt tartalmazó modul
A global_attribute_target más értékei nem engedélyezettek.
A szabványosított attribute_target nevek a következők event: , field, method, param, property, return, typeés typevar. Ezeket a célneveket csak a következő kontextusokban szabad használni:
-
event– esemény. -
field– mező. Egy mezőszerű eseménynek (azaz tartozék nélkülinek) (15.8.2. §) és egy automatikusan implementált tulajdonságnak (15.7.4. §) is lehet attribútuma ezzel a célval. -
method— konstruktor, finalizer, metódus, operátor, tulajdonság lekérése és beállítása, az indexelő be- és beszereli a tartozékokat, valamint esemény hozzáadása és eltávolítása. Egy mezőszerű esemény (azaz tartozék nélküli) attribútummal is rendelkezhet ezzel a céllal. -
param— tulajdonságkészlet-tartozék, indexelőkészlet-tartozék, esemény hozzáadása és eltávolítása, valamint egy paraméter egy konstruktorban, metódusban és operátorban. -
property— tulajdonság és indexelő. -
return— a delegált, a metódus, az operátor, a tulajdonság lekéri a tartozékot, az indexelő pedig a tartozékot. -
type— delegált, osztály, struct, enum és interfész. -
typevar— típusparaméter.
Bizonyos környezetek lehetővé teszik egy attribútum specifikációját egynél több célon. A program egy attribute_target_specifier beleszámítva explicit módon megadhatja a célt. Attribute_target_specifier nélkül az alapértelmezett érték van alkalmazva, de egy attribute_target_specifier is használható az alapértelmezett beállítás megerősítésére vagy felülbírálására. A környezetek a következőképpen lesznek feloldva:
- A delegált deklarációban szereplő attribútumok esetében az alapértelmezett cél a meghatalmazott. Ellenkező esetben, ha a attribute_target egyenlő:
-
type— a cél a meghatalmazott -
return— a cél a visszatérési érték
-
- Egy metódusdeklaráció egyik attribútuma esetében az alapértelmezett cél a metódus. Ellenkező esetben, ha a attribute_target egyenlő:
-
method— a cél a módszer -
return— a cél a visszatérési érték
-
- Egy operátor-deklaráció egyik attribútuma esetében az alapértelmezett cél az operátor. Ellenkező esetben, ha a attribute_target egyenlő:
-
method— a cél az operátor -
return— a cél a visszatérési érték
-
- Tulajdonság vagy indexelő deklarációhoz tartozó beolvasási kiegészítő deklaráción szereplő attribútum esetében az alapértelmezett cél a társított módszer. Ellenkező esetben, ha a attribute_target egyenlő:
-
method— a cél a társított módszer -
return— a cél a visszatérési érték
-
- Egy tulajdonsághoz vagy indexelő deklarációhoz beállított tartozékon megadott attribútum esetében az alapértelmezett cél a társított módszer. Ellenkező esetben, ha a attribute_target egyenlő:
-
method— a cél a társított módszer -
param— a cél a magányos implicit paraméter
-
- Az automatikusan implementált tulajdonságdeklarációban szereplő attribútumok esetében az alapértelmezett cél a tulajdonság. Ellenkező esetben, ha a attribute_target egyenlő:
-
field— a cél a tulajdonság fordító által létrehozott háttérmezője
-
- Egy eseménydeklarációban megadott attribútum esetében, amely kihagyja event_accessor_declarations az alapértelmezett cél az eseménydeklaráció. Ellenkező esetben, ha a attribute_target egyenlő:
-
event– a cél az eseménydeklaráció -
field— a cél a mező -
method— a célok a módszerek
-
- Olyan eseménydeklaráció esetén, amely nem hagyja ki event_accessor_declarations az alapértelmezett cél a metódus.
-
method— a cél a társított módszer -
param— a cél a magányos paraméter
-
Minden más kontextusban a attribute_target_specifier felvétele engedélyezett, de szükségtelen.
Példa: az osztálydeklaráció tartalmazhat vagy kihagyhat egy kijelölőt
type:[type: Author("Brian Kernighan")] class Class1 {} [Author("Dennis Ritchie")] class Class2 {}záró példa.
A implementációk más attribute_targetis elfogadhatnak, amelyek céljait a megvalósítás határozza meg. Az ilyen attribute_target nem felismerő végrehajtás figyelmeztetést ad ki, és figyelmen kívül hagyja a attribute_section.
Konvenció szerint az attribútumosztályok neve a következő utótaggal Attributevan elnevezve: . Egy attribute_name belefoglalhatja vagy kihagyhatja ezt az utótagot.
A attribute_name az alábbiak szerint oldjuk fel:
- Ha a attribute_name jobb oldali azonosítója szó szerinti azonosító (6.4.3. §), akkor a attribute_name type_name (7.8. §) oldja fel. Ha az eredmény nem a következő típusból
System.Attributeszármazik, fordítási időhiba lép fel. - Egyébként
- A attribute_name type_name (7.8. §) oldja fel, kivéve a hibákat. Ha ez a megoldás sikeres, és egy származtatott
System.Attributetípust eredményez, akkor a típus ennek a lépésnek az eredménye. - A karakterek
Attributehozzá vannak fűzve a attribute_name jobb oldali azonosítóhoz, és az eredményül kapott jogkivonat-sztring type_name ként (7.8. §) lesz feloldva, kivéve a hibákat. Ha ez a megoldás sikeres, és egy származtatottSystem.Attributetípust eredményez, akkor a típus ennek a lépésnek az eredménye.
- A attribute_name type_name (7.8. §) oldja fel, kivéve a hibákat. Ha ez a megoldás sikeres, és egy származtatott
Ha a fenti két lépés közül pontosan az egyik származik System.Attribute, akkor ez a típus a attribute_name eredménye. Ellenkező esetben fordítási időhiba lép fel.
Példa: Ha egy attribútumosztály található az utótaggal együtt és nélkül is, akkor kétértelműség és fordítási idő hibát eredményez. Ha a attribute_name úgy van beírva, hogy a jobb szélső azonosító egy szó szerinti azonosító (6.4.3. §), akkor csak utótag nélküli attribútummal egyeznek meg, ami lehetővé teszi az ilyen kétértelműség feloldását. A példa
[AttributeUsage(AttributeTargets.All)] public class Example : Attribute {} [AttributeUsage(AttributeTargets.All)] public class ExampleAttribute : Attribute {} [Example] // Error: ambiguity class Class1 {} [ExampleAttribute] // Refers to ExampleAttribute class Class2 {} [@Example] // Refers to Example class Class3 {} [@ExampleAttribute] // Refers to ExampleAttribute class Class4 {}két attribútumosztály neve
ExampleésExampleAttribute. Az attribútum[Example]nem egyértelmű, mivel hivatkozhat rá vagyExampleExampleAttribute. A szó szerinti azonosító használata lehetővé teszi a pontos szándék megadását ilyen ritka esetekben. Az attribútum[ExampleAttribute]nem egyértelmű (bár az lenne, ha lenne egy !nevűExampleAttributeAttributeattribútumosztály). Ha az osztályExampledeklarációja el lett távolítva, akkor mindkét attribútum a következő nevűExampleAttributeattribútumosztályra hivatkozik:[AttributeUsage(AttributeTargets.All)] public class ExampleAttribute : Attribute {} [Example] // Refers to ExampleAttribute class Class1 {} [ExampleAttribute] // Refers to ExampleAttribute class Class2 {} [@Example] // Error: no attribute named “Example” class Class3 {}záró példa
Fordítási időhiba, ha egy egyszer használt attribútumosztályt többször is használ ugyanazon az entitáson.
Példa: A példa
[AttributeUsage(AttributeTargets.Class)] public class HelpStringAttribute : Attribute { public HelpStringAttribute(string value) { Value = value; } public string Value { get; } } [HelpString("Description of Class1")] [HelpString("Another description of Class1")] // multiple uses not allowed public class Class1 {}fordítási idő hibát eredményez, mert az egyszer használatos attribútumosztályt többször is megpróbálja használni
HelpStringa deklarációnClass1.záró példa
A kifejezés E egy attribute_argument_expression , ha az alábbi állítások mindegyike igaz:
- A típus
Eegy attribútumparaméter típusa (23.2.4. §). - Fordításkor az érték
Eaz alábbiak egyikével oldható fel:- Állandó érték.
- Olyan
System.Typeobjektum, amely typeof_expression (12.8.18. §) használatával kapott, amely nem általános típust, zárt építésű típust (8.4.3. §) vagy kötetlen általános típust (8.4.4. §) határoz meg, de nyílt típust nem (8.4.3. §). - Attribute_argument_expression egydimenziós tömbje.
Példa:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Field)] public class TestAttribute : Attribute { public int P1 { get; set; } public Type P2 { get; set; } public object P3 { get; set; } } [Test(P1 = 1234, P3 = new int[]{1, 3, 5}, P2 = typeof(float))] class MyClass {} class C<T> { [Test(P2 = typeof(T))] // Error – T not a closed type. int x1; [Test(P2 = typeof(C<T>))] // Error – C<;T>; not a closed type. int x2; [Test(P2 = typeof(C<int>))] // Ok int x3; [Test(P2 = typeof(C<>))] // Ok int x4; }záró példa
A több részben deklarált típus attribútumait úgy határozzuk meg, hogy meghatározatlan sorrendben egyesítjük az egyes részek attribútumait. Ha ugyanazt az attribútumot több részre helyezi, az egyenértékű azzal, hogy az attribútumot többször is megadja a típuson.
Példa: A két rész:
[Attr1, Attr2("hello")] partial class A {} [Attr3, Attr2("goodbye")] partial class A {}egyenértékűek a következő egyetlen deklarációval:
[Attr1, Attr2("hello"), Attr3, Attr2("goodbye")] class A {}záró példa
A típusparaméterek attribútumai ugyanúgy egyesíthetők.
23.4 Attribútumpéldányok
23.4.1 Általános
Az attribútumpéldányok olyan példányok, amelyek futásidőben egy attribútumot jelölnek. Az attribútumokat attribútumosztály, pozícióargumentumok és elnevezett argumentumok határozzák meg. Az attribútumpéldány annak az attribútumosztálynak a példánya, amely a pozíció- és elnevezett argumentumokkal inicializálva van.
Az attribútumpéldányok lekérése a fordítási és a futásidejű feldolgozást is magában foglalja az alábbi alklámokban leírtak szerint.
23.4.2 Attribútum összeállítása
A programentitásokon megadott és positional_argument_list, T attribútumosztályt Ptartalmazó attribútumNa következő lépések végrehajtásával lesz összeállítva egy szerelvénybeE:A
- Kövesse a fordítási idő feldolgozási lépéseit összeállításához. Ezek a lépések fordítási időt eredményeznek, vagy meghatároznak egy példánykonstruktort
CT, amely futásidőben hívható meg. - Ha
Cnem rendelkezik nyilvános akadálymentességgel, fordítási időhiba lép fel. - Minden named_argument
Arga következőbenN:- Legyen
Namea . -
Namenem statikus írásvédett nyilvános mezőt vagy tulajdonságot kell azonosítania a következőnT: . HaTnincs ilyen mezője vagy tulajdonsága, akkor fordítási időhiba lép fel.
- Legyen
- Ha a positional_argument_list
Pvagy a named_argument_listNvalamelyik értéke típusúSystem.String, és az érték nem megfelelően van formázva a Unicode Szabványban meghatározottak szerint, akkor implementálási meghatározást kell alkalmazni, hogy a lefordított érték megegyezik-e a lekért futásidejű értékkel (23.4.3. §).Megjegyzés: Például egy olyan sztring, amely magas helyettesítő UTF-16 kódegységet tartalmaz, amelyet nem követ azonnal egy alacsony helyettesítő kódegység, nem jól formázott. végjegyzet
- Tárolja a következő információkat (az attribútum futásidejű példányosításához) a fordító által a szerelvény kimenetében az attribútumot tartalmazó program összeállítása eredményeképpen: az attribútumosztály
T, a példánykonstruktorCT, , aPés a kapcsolódó programentitássalN, az értékek fordítási időpontban teljesen feloldva.
23.4.3 Attribútumpéldány futásidejű lekérése
A 23.4.2. §-ban meghatározott kifejezések használatával a , T, C, és , attribútumpéldány által Pképviselt és Ntársított E attribútumpéldány futásidőben lekérhető a szerelvényből A az alábbi lépések végrehajtásával:
- Kövesse az űrlap egy object_creation_expression végrehajtásának futásidejű feldolgozási lépéseit a példánykonstruktor
new T(P)és a fordítási időpontbanCmeghatározott értékek használatával. Ezek a lépések kivételt eredményeznek, vagy létrehoznak egy példánytO.T - Minden named_argument
ArgNsorrendben:- Legyen
Namea . HaNamenem azonosít nem statikus nyilvános írási-olvasási mezőt vagy tulajdonságotO, akkor kivétel történik. - Nézzük
Valuemeg a attribute_argument_expression kiértékelésénekArgeredményét. - Ha
Nameazonosít egy mezőtO, akkor állítsa ezt a mezőt a következőreValue: . - Ellenkező esetben a Name (Név) tulajdonság azonosítja a (z) tulajdonságot
O. Állítsa ezt a tulajdonságot Érték értékre. - Az eredmény a
Opositional_argument_list és a named_argument_listTinicializált attribútumosztályPegy példánya.
- Legyen
Megjegyzés: A tárolás, ,
T,C,P(és társításNE) formátumaA, valamint a megadhatjaEés lekérniTkívánt mechanizmus, a ,C,PNA, a (és így az attribútumpéldány futásidőben történő lekérésének módja) túllépi a specifikáció hatókörét. végjegyzet
23.5 Fenntartott attribútumok
23.5.1 Általános
Számos attribútum valamilyen módon befolyásolja a nyelvet. Ezek az attribútumok a következők:
-
System.AttributeUsageAttribute(23.5.2. §), amely az attribútumosztályok felhasználási módjait ismerteti. -
System.Diagnostics.ConditionalAttribute(23.5.3. §) egy többfelhasználós attribútumosztály, amely feltételes metódusok és feltételes attribútumosztályok definiálására szolgál. Ez az attribútum egy feltételes fordítási szimbólum tesztelésével jelez egy feltételt. -
System.ObsoleteAttribute(23.5.4. §), amely egy tag elavultként való megjelölésére szolgál. -
System.Runtime.CompilerServices.AsyncMethodBuilderAttribute(23.5.5.5. §), amely egy aszinkron metódus feladatszerkesztőjének létrehozására szolgál. -
System.Runtime.CompilerServices.CallerLineNumberAttribute(23.5.6.2. §),System.Runtime.CompilerServices.CallerFilePathAttribute(23.5.6.3. §) ésSystem.Runtime.CompilerServices.CallerMemberNameAttribute(23.5.6.4. §), amelyek a hívó környezettel kapcsolatos információk megadására szolgálnak az opcionális paramétereknek. -
System.Runtime.CompilerServices.EnumeratorCancellationAttribute(23.5.8. §), amely a lemondási jogkivonat paraméterének megadására szolgál egy aszinkron iterátorban.
A null értékű statikus elemzési attribútumok (23.5.7.§) javíthatják a nulla képességekre és nullállapotokra generált figyelmeztetések helyességét (8.9.5. §).
A végrehajtási környezetek további implementáció által definiált attribútumokat biztosíthatnak, amelyek befolyásolják a C#-programok végrehajtását.
23.5.2 Az AttributeUsage attribútum
Az attribútum AttributeUsage az attribútumosztály használható módjának leírására szolgál.
Az attribútummal AttributeUsage ellátott osztálynak közvetlenül vagy közvetve kell származnie System.Attribute. Ellenkező esetben fordítási időhiba lép fel.
Megjegyzés: Az attribútum használatára példa: §23.2.2. végjegyzet
23.5.3 A feltételes attribútum
23.5.3.1 Általános
Az attribútum Conditional lehetővé teszi az s feltételes metódusés a feltételes attribútum osztályes definícióját.
23.5.3.2 Feltételes módszerek
Az attribútummal Conditional díszített metódus feltételes módszer. Így minden feltételes módszer társítva van az attribútumaiban Conditional deklarált feltételes fordítási szimbólumokkal.
Példa:
class Eg { [Conditional("ALPHA")] [Conditional("BETA")] public static void M() { // ... } }feltételes metódusként deklarál
Eg.Ma két feltételes fordításiALPHAszimbólumhoz ésBETA.záró példa
Egy feltételes metódus hívása akkor jelenik meg, ha egy vagy több társított feltételes fordítási szimbólum a hívás időpontjában van definiálva, ellenkező esetben a hívás nem lesz megadva.
A feltételes módszerekre a következő korlátozások vonatkoznak:
- A feltételes módszer egy class_declaration vagy struct_declaration metódusa. Fordítási időhiba akkor fordul elő, ha az
Conditionalattribútum egy felületi deklarációban megadott metóduson van megadva. - A feltételes módszer nem lehet tulajdonság, indexelő vagy esemény tartozéka.
- A feltételes módszer visszatérési
voidtípusa . - A feltételes módszert nem szabad megjelölni a
overridemódosítóval. A feltételes metódusok azonban megjelölhetők avirtualmódosítóval. Az ilyen módszer felülbírálása implicit módon feltételes, és nem jelölhető meg explicit módon attribútummalConditional. - A feltételes módszer nem lehet interfészmetódus alkalmazása. Ellenkező esetben fordítási időhiba lép fel.
- A feltételes módszer paraméterei nem lehetnek kimeneti paraméterek.
Megjegyzés: A (
AttributeUsage) attribútumok általábanAttributeTargets.Methodalkalmazhatók a tulajdonságok, indexelők és események tartozékaira. A fenti korlátozások tiltják azConditionalattribútum használatát. végjegyzet
Emellett fordítási idő hibát is tapasztal, ha egy meghatalmazott feltételes metódusból jön létre.
Példa: A példa
#define DEBUG using System; using System.Diagnostics; class Class1 { [Conditional("DEBUG")] public static void M() { Console.WriteLine("Executed Class1.M"); } } class Class2 { public static void Test() { Class1.M(); } }feltételes módszerként deklarál
Class1.M.Class2's metódus meghívjaTestezt a metódust. Mivel a feltételes fordítási szimbólumDEBUGdefiniálva van, haClass2.Testa rendszer meghívja, meghívjaM. Ha a szimbólumDEBUGnincs definiálva, akkorClass2.Testnem hívná megClass1.M.záró példa
Fontos tisztában lenni azzal, hogy a feltételes metódusra irányuló hívás felvételét vagy kizárását a hívás helyén lévő feltételes fordítási szimbólumok szabályozzák.
Példa: Az alábbi kódban
// File Class1.cs: using System; using System.Diagnostics; class Class1 { [Conditional("DEBUG")] public static void F() { Console.WriteLine("Executed Class1.F"); } } // File Class2.cs: #define DEBUG class Class2 { public static void G() { Class1.F(); // F is called } } // File Class3.cs: #undef DEBUG class Class3 { public static void H() { Class1.F(); // F is not called } }az osztályok
Class2ésClass3mindegyik a feltételes metódusClass1.Fhívásait tartalmazza, amely feltételes attól függően, hogy definiálva van-e.DEBUGMivel ez a szimbólum a környezetébenClass2van definiálva, de nemClass3, a rendszer a benne lévőFhívástClass2is tartalmazza, míg a betárcsázhatóFClass3hívás nincs megadva.záró példa
A feltételes módszerek használata az öröklési láncban zavaró lehet. A feltételes metódushoz az űrlapon basekeresztül base.Mindított hívásokra a normál feltételes metódushívási szabályok vonatkoznak.
Példa: Az alábbi kódban
// File Class1.cs using System; using System.Diagnostics; class Class1 { [Conditional("DEBUG")] public virtual void M() => Console.WriteLine("Class1.M executed"); } // File Class2.cs class Class2 : Class1 { public override void M() { Console.WriteLine("Class2.M executed"); base.M(); // base.M is not called! } } // File Class3.cs #define DEBUG class Class3 { public static void Main() { Class2 c = new Class2(); c.M(); // M is called } }
Class2AM /> az alaposztályban meghatározott hívásokat tartalmazza. Ez a hívás ki van hagyva, mert az alapmetódus feltételes, a szimbólum DEBUGjelenléte alapján, amely nincs meghatározva. Így a metódus csak "Class2.M executed" a konzolra ír. Az pp_declaration-kmegfontolt használata kiküszöbölheti az ilyen problémákat.záró példa
23.5.3.3 Feltételes attribútumosztályok
Egy vagy több attribútummal dekorált attribútumosztály (Conditional) feltételes attribútumosztály. A feltételes attribútumosztály így társítva van az attribútumaiban Conditional deklarált feltételes fordítási szimbólumokkal.
Példa:
[Conditional("ALPHA")] [Conditional("BETA")] public class TestAttribute : Attribute {}feltételes attribútumosztályként deklarálja
TestAttributea feltételes fordítási szimbólumokhozALPHAésBETAa .záró példa
A feltételes attribútum attribútumspecifikációi (23.3. §) akkor szerepelnek, ha egy vagy több társított feltételes fordítási szimbólum a specifikáció helyén van meghatározva, ellenkező esetben az attribútum specifikációja nem szerepel.
Fontos megjegyezni, hogy a feltételes attribútumosztály attribútumspecifikációjának felvételét vagy kizárását a specifikáció helyén található feltételes fordítási szimbólumok szabályozzák.
Példa: A példában
// File Test.cs: using System; using System.Diagnostics; [Conditional("DEBUG")] public class TestAttribute : Attribute {} // File Class1.cs: #define DEBUG [Test] // TestAttribute is specified class Class1 {} // File Class2.cs: #undef DEBUG [Test] // TestAttribute is not specified class Class2 {}osztályokat
Class1, ésClass2mindegyik attribútummalTestvan dekorálva, amely feltételes attól függően, hogy definiálva van-e vagy semDEBUG. Mivel ez a szimbólum a kontextusbanClass1van definiálva, de nemClass2, a tesztattribútumClass1specifikációja is szerepel, míg aTestrajta lévőClass2attribútum specifikációja nem szerepel.záró példa
23.5.4 Az elavult attribútum
Az attribútum Obsolete olyan típusok és tagok megjelölésére szolgál, amelyeket már nem szabad használni.
Ha egy program olyan típust vagy tagot használ, amelyet a Obsolete attribútum díszít, a fordító figyelmeztetést vagy hibát ad ki. A fordítónak figyelmeztetést kell adnia, ha nem ad meg hibaparamétert, vagy ha a hibaparaméter meg van adva, és falseértékkel rendelkezik. A fordító hibát ad ki, ha a hibaparaméter meg van adva, és trueértékkel rendelkezik.
Példa: Az alábbi kódban
[Obsolete("This class is obsolete; use class B instead")] class A { public void F() {} } class B { public void F() {} } class Test { static void Main() { A a = new A(); // Warning a.F(); } }az osztályt
AazObsoleteattribútum díszíti. Minden egyes használatAegy figyelmeztetésbenMainjelenik meg, amely tartalmazza a megadott üzenetet: "Ez az osztály elavult; helyett használja az osztálytB".záró példa
23.5.5 Az AsyncMethodBuilder attribútum
Ezt az attribútumot a 15.14.1 szakaszban leírják.
23.5.6 Hívóinformációs attribútumok
23.5.6.1 Általános
A naplózáshoz és a jelentéskészítéshez néha hasznos, ha a függvénytagok bizonyos fordítási időre vonatkozó információkat szereznek be a hívó kódról. A hívóinformációs attribútumok lehetővé teszik az információk transzparens átadását.
Ha egy választható paramétert a hívó-info attribútumok egyikével jegyzetel, a hívás megfelelő argumentumának kihagyása nem feltétlenül eredményezi az alapértelmezett paraméterérték helyettesítését. Ehelyett, ha a hívási környezettel kapcsolatos megadott információk rendelkezésre állnak, a rendszer argumentumértékként adja át az adatokat.
Példa:
public void Log( [CallerLineNumber] int line = -1, [CallerFilePath] string path = null, [CallerMemberName] string name = null ) { Console.WriteLine((line < 0) ? "No line" : "Line "+ line); Console.WriteLine((path == null) ? "No file path" : path); Console.WriteLine((name == null) ? "No member name" : name); }Az argumentumok nélküli hívás
Log()kinyomtatja a hívás sorszámát és fájl elérési útját, valamint annak a tagnak a nevét, amelyen belül a hívás történt.záró példa
A hívóinformációs attribútumok bárhol előfordulhatnak választható paramétereken, beleértve a delegált deklarációkat is. Az adott hívóinformációs attribútumok azonban korlátozzák az attribútumok típusait, így mindig implicit átalakítás lesz a helyettesítő értékről a paramétertípusra.
Hiba, ha ugyanazzal a hívó-info attribútummal rendelkezik egy részleges metódusdeklaráció definiáló és implementáló részének paraméterén. A rendszer csak a definiáló rész hívóinformációs attribútumait alkalmazza, míg a csak a megvalósító részben előforduló hívó-info attribútumokat a rendszer figyelmen kívül hagyja.
A hívó adatai nem befolyásolják a túlterhelés feloldását. Mivel az attribútumként megadott opcionális paraméterek továbbra is kimaradnak a hívó forráskódjából, a túlterhelés feloldása ugyanúgy figyelmen kívül hagyja ezeket a paramétereket, mint a többi kihagyott opcionális paramétert (12.6.4. §).
A hívóadatok csak akkor lesznek helyettesítve, ha a forráskód kifejezetten meghív egy függvényt. Az implicit meghívások, például az implicit szülőkonstruktorhívások nem rendelkeznek forráshellyel, és nem helyettesítik a hívó adatait. Emellett a dinamikusan kötött hívások nem helyettesítik a hívó adatait. Ha ilyen esetekben egy hívóinformációs attribútummal rendelkező paramétert hagy ki, a rendszer ehelyett a paraméter megadott alapértelmezett értékét használja.
Az egyik kivétel a lekérdezési kifejezések. Ezek szintaktikai expanzióknak minősülnek, és ha az általuk kibontott hívások nem kötelező paramétereket hagynak ki hívóinformációs attribútumokkal, a hívó információi lecserélődnek. A használt hely annak a lekérdezési záradéknak a helye, ahonnan a hívást létrehozták.
Ha egy adott paraméteren egynél több hívó-info attribútum van megadva, a rendszer a következő sorrendben ismeri fel őket: CallerLineNumber, CallerFilePath, CallerMemberName. Vegye figyelembe a következő paraméterdeklarációt:
[CallerMemberName, CallerFilePath, CallerLineNumber] object p = ...
CallerLineNumber elsőbbséget élvez, a másik két attribútumot pedig figyelmen kívül hagyja. Ha CallerLineNumber nem lett volna megadva, CallerFilePath elsőbbséget élvezne, és CallerMemberName figyelmen kívül hagyná. Ezeknek az attribútumoknak a lexikális sorrendje irreleváns.
23.5.6.2 A CallerLineNumber attribútum
Az attribútum System.Runtime.CompilerServices.CallerLineNumberAttribute akkor engedélyezhető választható paramétereken, ha az állandó értékről a paraméter típusára standard implicit átalakítás (int.MaxValue. §) van. Ez biztosítja, hogy az adott értékig nem negatív sorszám hiba nélkül átadható legyen.
Ha a forráskód egy helyéről történő függvényhívás kihagy egy választható paramétert a CallerLineNumberAttributeforráskódban, akkor a rendszer az alapértelmezett paraméterérték helyett argumentumként az adott hely sorszámát képviselő numerikus literált használja.
Ha a meghívás több sorra is kiterjed, a kiválasztott sor implementációfüggő.
A sorszámot az irányelvek befolyásolhatják #line (6.5.8. §).
23.5.6.3 A CallerFilePath attribútum
Az attribútum System.Runtime.CompilerServices.CallerFilePathAttribute akkor engedélyezhető választható paramétereken, ha a paraméter típusához standard implicit átalakítás (string. §) tartozik.
Ha a forráskód egy helyéről történő függvényhívás kihagy egy választható paramétert a forráskódban, akkor az CallerFilePathAttributealapértelmezett paraméterérték helyett az adott hely fájlútvonalát képviselő sztringkonstanst használ a rendszer a meghívás argumentumaként.
A fájl elérési útjának formátuma implementációfüggő.
A fájl elérési útját az irányelvek befolyásolhatják #line (6.5.8. §).
23.5.6.4 A CallerMemberName attribútum
Az attribútum System.Runtime.CompilerServices.CallerMemberNameAttribute akkor engedélyezhető választható paramétereken, ha a paraméter típusához standard implicit átalakítás (string. §) tartozik.
Ha egy függvényhívás egy függvénytag törzsén belüli helyről vagy a függvénytagra alkalmazott attribútumon belül, vagy annak visszatérési típusa, a forráskódban szereplő paraméterek vagy típusparaméterek kihagynak egy választható paramétert a CallerMemberNameAttributekövetkezővel, akkor a rendszer az alapértelmezett paraméterérték helyett argumentumként az adott tag nevét képviselő karakterlánc-literált használja a meghíváshoz.
Az általános metódusokon belül előforduló meghívások esetén a típusparaméter-lista nélkül csak a metódus nevét használja a rendszer.
Az explicit felülettag-implementációkban előforduló meghívások esetében a rendszer csak magát a metódusnevet használja az előző felületi minősítés nélkül.
A tulajdonságon vagy eseményen belüli meghívások esetén a használt tagnév maga a tulajdonság vagy az esemény neve.
Az indexelő tartozékaiban előforduló meghívások esetén a használt tagnév az indexelőtagon (IndexerNameAttribute) megadott név, ha van ilyen, vagy az alapértelmezett névItem.
A mező- vagy esemény-inicializálókban előforduló meghívások esetén a használt tagnév az inicializálandó mező vagy esemény neve.
A példánykonstruktorok, statikus konstruktorok, véglegesítők és operátorok deklarációiban előforduló meghívások esetében a használt tagnév implementációfüggő.
23.5.7 Kódelemzési attribútumok
23.5.7.1 Általános
Az alcím attribútumai további információkat nyújtanak a nullabilitás és null állapotú diagnosztikát biztosító fordítók támogatásához (§8.9.5). A nullállapot-diagnosztika elvégzéséhez nincs szükség fordítóra. Ezeknek az attribútumoknak a jelenléte vagy hiánya nem befolyásolja a program nyelvét és viselkedését. A nullállapot-diagnosztikát nem biztosító fordítónak be kell olvasnia és figyelmen kívül kell hagynia ezeknek az attribútumoknak a jelenlétét. A nullállapot-diagnosztikát biztosító fordítónak az ebben az albekezdésben meghatározott jelentést kell használnia azokra az attribútumokra, amelyeket diagnosztikai célból használ.
A kódelemzési attribútumok névtérben System.Diagnostics.CodeAnalysisvannak deklarálva.
| Attribútum | Jelentés |
|---|---|
AllowNull (23.5.7.2. §) |
A nem null értékű argumentumok lehetnek null értékűek. |
DisallowNull (23.5.7.3. §) |
A null értékű argumentumok soha nem lehetnek null értékűek. |
MaybeNull (23.5.7.6. §) |
A nem null értékű visszatérési érték null értékű lehet. |
NotNull (23.5.7.8. §) |
A null értékű visszatérési érték soha nem lesz null értékű. |
MaybeNullWhen (23.5.7.7. §) |
A nem null értékű argumentum null értékű lehet, ha a metódus a megadott bool értéket adja vissza. |
NotNullWhen (23.5.7.10. §) |
A null értékű argumentumok nem lesznek null értékűek, ha a metódus a megadott bool értéket adja vissza. |
NotNullIfNotNull (23.5.7.9. §) |
A visszatérési érték nem null, ha a megadott paraméter argumentuma nem null. |
DoesNotReturn (23.5.7.4. §) |
Ez a metódus soha nem tér vissza. |
DoesNotReturnIf (23.5.7.5. §) |
Ez a metódus soha nem ad vissza értéket, ha a társított bool paraméter a megadott értékkel rendelkezik. |
A 23.5.7.1. § -ban az alábbi alklámok feltételesen normatívak.
23.5.7.2 Az AllowNull attribútum
Megadja, hogy a null érték akkor is engedélyezett bemenetként, ha a megfelelő típus nem engedélyezi azt.
Példa: Fontolja meg az alábbi olvasási/írási
nulltulajdonságot, amely soha nem ad vissza, mert ésszerű alapértelmezett értékkel rendelkezik. A felhasználó azonban null értéket adhat a beállított tartozéknak, hogy a tulajdonságot az alapértelmezett értékre állítsa.#nullable enable public class X { [AllowNull] public string ScreenName { get => _screenName; set => _screenName = value ?? GenerateRandomScreenName(); } private string _screenName = GenerateRandomScreenName(); private static string GenerateRandomScreenName() => ...; }Tekintettel a tulajdonság készlettartozékának alábbi használatára
var v = new X(); v.ScreenName = null; // may warn without attribute AllowNullaz attribútum nélkül a fordító figyelmeztetést generálhat, mert úgy tűnik, hogy a nem null értékű tulajdonság null értékűre van állítva. Az attribútum jelenléte letiltja ezt a figyelmeztetést. záró példa
23.5.7.3 A DisallowNull attribútum
Megadja, hogy a null érték nem engedélyezett bemenetként, még akkor is, ha a megfelelő típus engedélyezi.
Példa: Vegye figyelembe az alábbi tulajdonságot, amelyben a null az alapértelmezett érték, de az ügyfelek csak nem null értékűre állíthatják be.
#nullable enable public class X { [DisallowNull] public string? ReviewComment { get => _comment; set => _comment = value ?? throw new ArgumentNullException(nameof(value), "Cannot set to null"); } private string? _comment = default; }A lekérő metódus visszaadhatja a
nullalapértelmezett értékét, ezért a fordító figyelmeztetheti, hogy a hozzáférést megelőzően ellenőrizni kell. Emellett arra is figyelmezteti a hívókat, hogy annak ellenére, hogy null értékű lehet, a hívónak nem szabad explicit módon null értékre állítania. záró példa
23.5.7.4 A DoesNotReturn attribútum
Azt adja meg, hogy egy adott metódus soha nem ad vissza.
Példa: Fontolja meg a következőket:
public class X { [DoesNotReturn] private void FailFast() => throw new InvalidOperationException(); public void SetState(object? containedField) { if ((!isInitialized) || (containedField == null)) { FailFast(); } // null check not needed. _field = containedField; } private bool isInitialized = false; private object _field; }Az attribútum jelenléte számos módon segíti a fordítót. Először is, a fordító figyelmeztetést adhat ki, ha van egy olyan elérési út, ahol a metódus kivétel dobása nélkül kiléphet. Másodszor, a fordító el tudja tiltani a null értékű figyelmeztetéseket bármely kódban az adott metódus meghívása után, amíg meg nem találja a megfelelő fogási záradékot. Harmadszor, a nem elérhető kód semmilyen null állapotra nem lesz hatással.
Az attribútum nem változtatja meg az elérhetőséget (13.2.§) vagy a határozott hozzárendelést (§9.4) az attribútum jelenléte alapján. Csak a nullitásra vonatkozó figyelmeztetések befolyásolására használható. záró példa
23.5.7.5 A DoesNotReturnIf attribútum
Azt adja meg, hogy egy adott metódus soha nem ad vissza értéket, ha a társított bool paraméter a megadott értékkel rendelkezik.
Példa: Fontolja meg a következőket:
#nullable enable public class X { private void ThrowIfNull([DoesNotReturnIf(true)] bool isNull, string argumentName) { if (!isNull) { throw new ArgumentException(argumentName, $"argument {argumentName} can't be null"); } } public void SetFieldState(object containedField) { ThrowIfNull(containedField == null, nameof(containedField)); // unreachable code when "isInitialized" is false: _field = containedField; } private bool isInitialized = false; private object _field = default!; }záró példa
23.5.7.6 A MaybeNull attribútum
Azt határozza meg, hogy a nem null értékű visszatérési érték null értékű lehet.
Példa: Fontolja meg a következő általános módszert:
#nullable enable public T? Find<T>(IEnumerable<T> sequence, Func<T, bool> predicate) { ... }Ennek a kódnak az a lényege, hogy ha
Tlecserélistring,T?akkor null értékű széljegyzet lesz. Ez a kód azonban nem jogi, mertTnincs hivatkozási típusra korlátozva. Az attribútum hozzáadása azonban megoldja a problémát:#nullable enable [return: MaybeNull] public T Find<T>(IEnumerable<T> sequence, Func<T, bool> predicate) { ... }Az attribútum tájékoztatja a hívókat, hogy a szerződés nem null értékű típust jelent, de a visszatérési érték valójában
nulllehet . záró példa
23.5.7.7 A MaybeNullWhen attribútum
Azt adja meg, hogy nem null értékű argumentum lehet null , ha a metódus a megadott bool értéket adja vissza. Ez hasonló az MaybeNull attribútumhoz (23.5.7.6. §), de tartalmaz egy paramétert a megadott visszatérési értékhez.
23.5.7.8 A NotNull attribútum
Azt adja meg, hogy a null értékű érték soha nem lesz null , ha a metódus (a dobás helyett) ad vissza.
Példa: Fontolja meg a következőket:
#nullable enable public static void ThrowWhenNull([NotNull] object? value, string valueExpression = "") => _ = value ?? throw new ArgumentNullException(valueExpression); public static void LogMessage(string? message) { ThrowWhenNull(message, nameof(message)); Console.WriteLine(message.Length); }Ha engedélyezve vannak a null értékű hivatkozástípusok, a metódus
ThrowWhenNullfigyelmeztetések nélkül fordítható le. Ha ez a metódus visszatér, azvalueargumentum garantáltan nemnulllesz . Elfogadható azonban null hivatkozással meghívniThrowWhenNull. záró példa
23.5.7.9 A NotNullIfNotNull attribútum
Azt adja meg, hogy a visszaadott érték nem null akkor, ha a megadott paraméter argumentuma nem null.
Példa: Egy visszatérési érték null állapota egy vagy több argumentum null állapotától függhet. A fordítóelemzés segítése érdekében a
nullattribútum használható, ha egy metódus mindig nem null értéket ad vissza, amikor bizonyos argumentumok nemNotNullIfNotNullértékűek. Fontolja meg a következő módszert:#nullable enable string GetTopLevelDomainFromFullUrl(string url) { ... }Ha az
urlargumentum nemnull,nullakkor a függvény nem adja vissza. Ha engedélyezve vannak a null értékű hivatkozások, az aláírás megfelelően működik, feltéve, hogy az API soha nem fogad el null argumentumot. Ha azonban az argumentum null értékű lehet, akkor a visszatérési érték is null lehet. A szerződés helyes kifejezéséhez fűzze megjegyzésként ezt a módszert az alábbiak szerint:#nullable enable [return: NotNullIfNotNull("url")] string? GetTopLevelDomainFromFullUrl(string? url) { ... }záró példa
23.5.7.10 A NotNullWhen attribútum
Azt adja meg, hogy a null értékű argumentum nem lesz akkor, null ha a metódus a megadott bool értéket adja vissza.
Példa: A kódtár metódus
String.IsNullOrEmpty(String)akkor adtruevissza, ha az argumentumnullvagy egy üres sztring. Ez a null-ellenőrzés egyik formája: A hívóknak nem kell null-ellenőrzéssel ellenőrizni az argumentumotfalse, ha a metódus visszatér. Ha egy ilyen null értékű metódust szeretne felismerni, állítsa a paramétertípust null értékű hivatkozástípussá, és adja hozzá a NotNullWhen attribútumot:#nullable enable bool IsNullOrEmpty([NotNullWhen(false)] string? value) { ... }záró példa
23.5.8 Az EnumeratorCancellation attribútum
Megadja az aszinkron CancellationToken iterátor paraméterét (15.15. §). Ennek a paraméternek az argumentumát össze kell kapcsolni a megadott IAsyncEnumerable<T>.GetAsyncEnumerator(CancellationToken)argumentummal. Ezt az egyesített jogkivonatot IAsyncEnumerator<T>.MoveNextAsync() a (15.15.5.2. §) kell lekérdezni. A jogkivonatokat egyetlen jogkivonatba kell egyesíteni, mintha az CancellationToken.CreateLinkedTokenSource adott jogkivonat és annak tulajdonsága Token lenne. Az egyesített jogkivonat akkor lesz megszakítva, ha a két forrásjogkivonat egyikét megszakítja. Az egyesített jogkivonat az aszinkron iterátormetódus (15.15.15. §) argumentuma a metódus törzsében.
Hiba, ha az System.Runtime.CompilerServices.EnumeratorCancellation attribútum egynél több paraméterre van alkalmazva. A fordító figyelmeztetést okozhat, ha:
- Az
EnumeratorCancellationattribútum egy olyan paraméterre lesz alkalmazva, amely nemCancellationTokenaz , - vagy ha az
EnumeratorCancellationattribútum nem aszinkron iterátort használó metódus paraméterére van alkalmazva (15.15.§), - vagy ha az
EnumeratorCancellationattribútum egy olyan metódus paraméterére van alkalmazva, amely aszinkron számbavételi felületet (15.15.3. §) aszinkron enumerátori felület helyett aszinkron enumerátori interfészt ad vissza (15.15.2. §).
Az iterátor nem fér hozzá az CancellationToken argumentumhoz GetAsyncEnumerator , ha egyetlen attribútum sem rendelkezik ezzel a paramétersel.
Példa: A metódus
GetStringsAsync()egy aszinkron iterátor. Mielőtt bármilyen munkát végez a következő érték lekérése érdekében, ellenőrzi a lemondási jogkivonatot annak megállapításához, hogy az iterációt le kell-e mondani. Ha a rendszer lemondást kér, nem történik további művelet.public static async Task ExampleCombination() { var sourceOne = new CancellationTokenSource(); var sourceTwo = new CancellationTokenSource(); await using (IAsyncEnumerator<string> enumerator = GetStringsAsync(sourceOne.Token).GetAsyncEnumerator(sourceTwo.Token)) { while (await enumerator.MoveNextAsync()) { string number = enumerator.Current; if (number == "8") sourceOne.Cancel(); if (number == "5") sourceTwo.Cancel(); Console.WriteLine(number); } } } static async IAsyncEnumerable<string> GetStringsAsync( [EnumeratorCancellation] CancellationToken token) { for (int i = 0; i < 10; i++) { if (token.IsCancellationRequested) yield break; await Task.Delay(1000, token); yield return i.ToString(); } }záró példa
23.6 Az együttműködés attribútumai
Más nyelvekkel való együttműködés esetén az indexelő indexelt tulajdonságok használatával implementálható. Ha egy indexelőhöz nincs IndexerName attribútum, a rendszer alapértelmezés szerint a nevet Item használja. Az IndexerName attribútum lehetővé teszi, hogy a fejlesztő felülbírálja ezt az alapértelmezett értéket, és adjon meg egy másik nevet.
Példa: Alapértelmezés szerint az indexelő neve .
ItemEzt felül lehet bírálni az alábbiak szerint:[System.Runtime.CompilerServices.IndexerName("TheItem")] public int this[int index] { get { ... } set { ... } }Most az indexelő neve .
TheItemzáró példa
ECMA C# draft specification