22 Öznitelikler
22.1 Genel
C# dilinin büyük bölümü programcının programda tanımlanan varlıklar hakkında bildirim temelli bilgiler belirtmesini sağlar. Örneğin, bir sınıftaki bir yöntemin erişilebilirliği, method_modifier private
süslenerek belirtilir.
C# programcıların öznitelikler olarak adlandırılan yeni bildirim temelli bilgi türleri icat etmelerini sağlar. Programcılar daha sonra çeşitli program varlıklarına öznitelik ekleyebilir ve çalışma zamanı ortamında öznitelik bilgilerini alabilir.
Not: Örneğin, bir çerçeve belirli program öğelerine (sınıflar ve yöntemler gibi) yerleştirilebilen bir
HelpAttribute
öznitelik tanımlayarak bu program öğelerinden belgelerine eşleme sağlayabilir. son not
Öznitelikler, konumsal ve adlandırılmış parametrelere (§22.2.3) sahip olabilecek öznitelik sınıflarının (§22.2) bildirimiyle tanımlanır. Öznitelikler, öznitelik belirtimleri (§22.3) kullanılarak bir C# programındaki varlıklara eklenir ve çalışma zamanında öznitelik örnekleri (§22.4) olarak alınabilir.
22.2 Öznitelik sınıfları
22.2.1 Genel
soyut sınıfından türetilen bir sınıfSystem.Attribute
, doğrudan veya dolaylı olarak bir öznitelik sınıfıdır. Öznitelik sınıfının bildirimi, program varlıklarına yerleştirilebilen yeni bir öznitelik türü tanımlar. Kural gereği, öznitelik sınıfları sonekiyle Attribute
adlandırılır. Bir özniteliğin kullanımları bu son eki içerebilir veya atlar.
Genel sınıf bildirimi, doğrudan veya dolaylı temel sınıf olarak kullanılmayacaktır System.Attribute
.
Örnek:
public class B : Attribute {} public class C<T> : B {} // Error – generic cannot be an attribute
son örnek
22.2.2 Öznitelik kullanımı
Özniteliği AttributeUsage
(§22.5.2), bir öznitelik sınıfının nasıl kullanılabileceğini açıklamak için kullanılır.
AttributeUsage
bir öznitelik sınıfının, üzerinde kullanılabileceğini program varlıklarının türlerini belirtmesini sağlayan bir konumsal parametresi (§22.2.3) vardır.
Örnek: Aşağıdaki örnek, yalnızca class_declaration ve
SimpleAttribute
interface_declarationüzerine yerleştirilebilen adlı bir öznitelik sınıfını tanımlar ve özniteliğinSimple
çeşitli kullanımlarını gösterir.[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface)] public class SimpleAttribute : Attribute { ... } [Simple] class Class1 {...} [Simple] interface Interface1 {...}
Bu öznitelik adıyla
SimpleAttribute
tanımlanmış olsa da,Attribute
bu öznitelik kullanıldığında, sonek atlanabilir ve kısa adıylaSimple
sonuçlanabilir. Bu nedenle, yukarıdaki örnek aşağıdakine eşdeğerdir[SimpleAttribute] class Class1 {...} [SimpleAttribute] interface Interface1 {...}
son örnek
AttributeUsage
adlı bir parametreye (§22.2.3) AllowMultiple
sahiptir. Bu parametre, özniteliğin belirli bir varlık için birden çok kez belirtilip belirtilemeyeceğini gösterir. Öznitelik sınıfı için true ise AllowMultiple
, bu öznitelik sınıfı çok kullanımlı bir öznitelik sınıfıdır ve bir varlıkta birden çok kez belirtilebilir. Öznitelik sınıfı için false ise veya belirtilmemişse AllowMultiple
, bu öznitelik sınıfı tek kullanımlık bir öznitelik sınıfıdır ve bir varlıkta en fazla bir kez belirtilebilir.
Örnek: Aşağıdaki örnek adlı
AuthorAttribute
çok kullanımlı bir öznitelik sınıfını tanımlar ve özniteliğininAuthor
iki kullanımına sahip bir sınıf bildirimi gösterir:[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 { ... }
son örnek
AttributeUsage
adlı başka bir adlandırılmış parametreye (§22.2.3) Inherited
sahiptir. Bu parametre, bir temel sınıfta belirtildiğinde özniteliğin bu temel sınıftan türetilen sınıflar tarafından da devralınıp devralınmadığını gösterir. Bir Inherited
öznitelik sınıfı için true ise, bu öznitelik devralınır. Bir Inherited
öznitelik sınıfı için false ise, bu öznitelik devralınmıyor demektir. Belirtilmemişse, varsayılan değeri true olur.
Öznitelik sınıfında X
AttributeUsage
olduğu gibi, öznitelik eklenmemiş
class X : Attribute { ... }
aşağıdakilere eşdeğerdir:
[AttributeUsage(
AttributeTargets.All,
AllowMultiple = false,
Inherited = true)
]
class X : Attribute { ... }
22.2.3 Konumsal ve adlandırılmış parametreler
Öznitelik sınıflarının konumsal parametrelerive adlandırılmış parametreleris olabilir. Bir öznitelik sınıfı için her genel örnek oluşturucu, bu öznitelik sınıfı için geçerli bir konumsal parametre dizisi tanımlar. Öznitelik sınıfı için statik olmayan her genel okuma-yazma alanı ve özelliği, öznitelik sınıfı için adlandırılmış bir parametre tanımlar. Bir özelliğin adlandırılmış parametre tanımlaması için, bu özelliğin hem genel alma erişimcisine hem de ortak küme erişimcisine sahip olması gerekir.
Örnek: Aşağıdaki örnek, adlı
HelpAttribute
bir konumsal parametresi olan ve adlı bir parametresiurl
Topic
olan bir öznitelik sınıfını tanımlar. Statik ve genel olmasa da, özelliğiUrl
adlandırılmış bir parametre tanımlamaz, çünkü okuma-yazma değildir. Bu özniteliğin iki kullanımları da gösterilir:[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 { }
son örnek
22.2.4 Öznitelik parametre türleri
Bir öznitelik sınıfı için konumsal ve adlandırılmış parametre türleri öznitelik parametre türleriyle sınırlıdır; bunlar:
- Aşağıdaki türlerden biri: , , , ,
bool
,byte
, ,char
, ,double
,float
int
long
sbyte
short
string
.uint
ulong
ushort
- türü
object
. - türü
System.Type
. - Sabit listesi türleri.
- Yukarıdaki türlerin tek boyutlu dizileri.
- Bu türlerden birine sahip olmayan bir oluşturucu bağımsız değişkeni veya ortak alan, öznitelik belirtiminde konumsal veya adlandırılmış parametre olarak kullanılmamalıdır.
22.3 Öznitelik belirtimi
Öznitelik belirtimi , daha önce tanımlanmış bir özniteliğin bir program varlığına uygulanmasıdır. Öznitelik, program varlığı için belirtilen ek bildirim temelli bilgilerin bir parçasıdır. Öznitelikler genel kapsamda (içeren derleme veya modüldeki öznitelikleri belirtmek için) ve type_declaration s (§14.7), class_member_declarations (§15.3), interface_member_declarations (§15.3) için belirtilebilir 18.4), struct_member_declarations (§16.3), enum_member_declarations (§19.2), accessor_declarations (§15.7.3), event_accessor_ bildirims (§15.8), parameter_listöğeleri (§15.6.2) ve type_parameter_listöğeleri (§15.2.3).
Öznitelikler öznitelik bölümlerinde belirtilir. Öznitelik bölümü, bir veya daha fazla özniteliğin virgülle ayrılmış listesini çevreleyen bir çift köşeli ayraçtan oluşur. Özniteliklerin böyle bir listede belirtilme sırası ve aynı program varlığına eklenen bölümlerin düzenlenme sırası önemli değildir. Örneğin , , [A][B]
[B][A]
ve [A, B]
öznitelik belirtimleri [B, A]
eşdeğerdir.
global_attributes
: global_attribute_section+
;
global_attribute_section
: '[' global_attribute_target_specifier attribute_list ']'
| '[' 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_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
;
Üretim global_attribute_target ve aşağıdaki metinde tanımlayıcı, eşitliğin §6.4.3assembly
tanımlandığı veya module
değerine eşit bir yazım denetimine sahip olmalıdır.
Üretim attribute_target ve aşağıdaki metinde tanımlayıcı, yukarıdakiyle aynı eşitlik tanımını kullanarak veya assembly
değerine eşit module
olmayan bir yazım denetimine sahip olmalıdır.
Öznitelik, bir attribute_name ve isteğe bağlı konumsal ve adlandırılmış bağımsız değişkenlerin bir listesinden oluşur. Adlandırılmış bağımsız değişkenlerin önüne konumsal bağımsız değişkenler (varsa) eklenir. Konumsal bağımsız değişken bir attribute_argument_expression oluşur; adlandırılmış bağımsız değişken bir addan, ardından eşittir işaretinden ve ardından basit atamayla aynı kurallarla kısıtlanan bir attribute_argument_expression oluşur. Adlandırılmış bağımsız değişkenlerin sırası önemli değildir.
Not: Kolaylık sağlamak için, bir array_initializer (§17.7) içinde bir virgüle izin verilirken olduğu gibi, bir global_attribute_section ve attribute_section de sondaki virgüle izin verilir. son not
attribute_name bir öznitelik sınıfı tanımlar.
Bir öznitelik genel düzeyde yerleştirildiğinde, bir global_attribute_target_specifier gerekir. global_attribute_target şuna eşit olduğunda:
-
assembly
— hedef, içeren derlemedir -
module
— hedef, içeren modüldür
global_attribute_target için başka değere izin verilmez.
Standartlaştırılmış attribute_target adları , , event
field
, , method
, param
, property
, return
ve type
şeklindedirtypevar
. Bu hedef adları yalnızca aşağıdaki bağlamlarda kullanılmalıdır:
-
event
— bir etkinlik. -
field
— bir alan. Alan benzeri bir olay (örneğin, erişimcileri olmayan bir olay) (§15.8.2) ve otomatik olarak uygulanan bir özellik (§15.7.4) de bu hedefe sahip bir özniteliğe sahip olabilir. -
method
— oluşturucu, sonlandırıcı, yöntem, işleç, özellik alma ve ayarlama erişimcileri, dizin oluşturucu erişimcileri alma ve ayarlama ve olay ekleme ve kaldırma erişimcileri. Alan benzeri bir olayın (örneğin, erişimcileri olmayan bir olay) bu hedefe sahip bir özniteliği de olabilir. -
param
— bir özellik kümesi erişimcisi, dizin oluşturucu kümesi erişimcisi, olay ekleme ve kaldırma erişimcileri ve oluşturucu, yöntem ve işleçteki bir parametre. -
property
— bir özellik ve dizin oluşturucu. -
return
— temsilci, yöntem, işleç, özellik alma erişimcisi ve dizin oluşturucu alma erişimcisi. -
type
— temsilci, sınıf, yapı, numaralandırma ve arabirim. -
typevar
— bir tür parametresi.
Belirli bağlamlar birden fazla hedefte özniteliğin belirtimine izin verir. Bir program, bir attribute_target_specifier ekleyerek hedefi açıkça belirtebilir. attribute_target_specifier olmadan bir varsayılan uygulanır, ancak varsayılanı doğrulamak veya geçersiz kılmak için bir attribute_target_specifier kullanılabilir. Bağlamlar aşağıdaki gibi çözümlenir:
- Temsilci bildirimindeki bir öznitelik için varsayılan hedef temsilcidir. Aksi takdirde attribute_target şuna eşit olduğunda:
-
type
— hedef temsilcidir -
return
— hedef, dönüş değeridir
-
- Yöntem bildirimindeki bir öznitelik için varsayılan hedef yöntemidir. Aksi takdirde attribute_target şuna eşit olduğunda:
-
method
— hedef yöntemidir -
return
— hedef, dönüş değeridir
-
- Bir işleç bildirimindeki bir öznitelik için varsayılan hedef işleçtir. Aksi takdirde attribute_target şuna eşit olduğunda:
-
method
— hedef işlecidir -
return
— hedef, dönüş değeridir
-
- Bir özellik veya dizin oluşturucu bildirimi için get erişimci bildirimindeki bir öznitelik için, varsayılan hedef ilişkili yöntemdir. Aksi takdirde attribute_target şuna eşit olduğunda:
-
method
— hedef ilişkili yöntemdir -
return
— hedef, dönüş değeridir
-
- Bir özellik veya dizin oluşturucu bildirimi için küme erişimcisinde belirtilen bir öznitelik için, varsayılan hedef ilişkili yöntemdir. Aksi takdirde attribute_target şuna eşit olduğunda:
-
method
— hedef ilişkili yöntemdir -
param
— hedef, tek örtük parametredir
-
- Otomatik olarak uygulanan özellik bildirimindeki bir öznitelik için varsayılan hedef özelliğidir. Aksi takdirde attribute_target şuna eşit olduğunda:
-
field
— hedef, özelliği için derleyici tarafından oluşturulan yedekleme alanıdır
-
- Varsayılan hedef, olay bildirimi event_accessor_declarations atlayan bir olay bildiriminde belirtilen öznitelik için. Aksi takdirde attribute_target şuna eşit olduğunda:
-
event
— hedef olay bildirimidir -
field
— hedef alanıdır -
method
— hedefler yöntemlerdir
-
- Atlanmayan bir olay bildirimi durumunda, varsayılan hedef yöntemi event_accessor_declarations .
-
method
— hedef ilişkili yöntemdir -
param
— hedef tek parametredir
-
Diğer tüm bağlamlarda, bir attribute_target_specifier eklenmesine izin verilir ancak gereksizdir.
Örnek: bir sınıf bildirimi belirticiyi
type
içerebilir veya atlar:[type: Author("Brian Kernighan")] class Class1 {} [Author("Dennis Ritchie")] class Class2 {}
bitiş örneği.
Bir uygulama, amaçları uygulama tanımlı olan diğer attribute_targetkabul edebilir. Böyle bir attribute_target tanımayan bir uygulama bir uyarı yayınlar ve içeren attribute_section yok sayar.
Kural gereği, öznitelik sınıfları sonekiyle Attribute
adlandırılır. bir attribute_name bu son eki içerebilir veya atlayabilir. Özellikle, bir attribute_name aşağıdaki gibi çözümlenir:
- attribute_name en doğru tanımlayıcısı bir ayrıntılı tanımlayıcı (§6.4.3) ise, attribute_name type_name(§7.8) olarak çözümlenir. Sonuç, türünden
System.Attribute
türetilmiş bir tür değilse, derleme zamanı hatası oluşur. - Yoksa
- Hatalar gizlenmezseattribute_name type_name (§7.8) olarak çözümlenir. Bu çözüm başarılı olursa ve türünden
System.Attribute
türetilmiş bir türle sonuçlanırsa, tür bu adımın sonucudur. - Karakterler
Attribute
attribute_name en sağdaki tanımlayıcıya eklenir ve sonuçta elde edilen belirteç dizesi type_name (§7.8) olarak çözümlenir, ancak hatalar gizlenemez. Bu çözüm başarılı olursa ve türündenSystem.Attribute
türetilmiş bir türle sonuçlanırsa, tür bu adımın sonucudur.
- Hatalar gizlenmezseattribute_name type_name (§7.8) olarak çözümlenir. Bu çözüm başarılı olursa ve türünden
Yukarıdaki iki adımdan tam olarak biri türünden System.Attribute
türetilirse, bu tür attribute_name sonucudur. Aksi takdirde bir derleme zamanı hatası oluşur.
Örnek: Bu sonekle birlikte ve olmadan bir öznitelik sınıfı bulunursa, bir belirsizlik ve derleme zamanı hata sonuçları vardır. attribute_name en sağ tanımlayıcısı bir ayrıntılı tanımlayıcı (§6.4.3) olacak şekilde yazılırsa, yalnızca son eki olmayan bir öznitelik eşleştirilir ve bu nedenle böyle bir belirsizliğin çözülmesini sağlar. Örnek
[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 {}
ve
Example
adlıExampleAttribute
iki öznitelik sınıfı gösterir. özniteliği[Example]
belirsizdir, çünkü veyaExample
öğesine başvurabilirExampleAttribute
. Ayrıntılı tanımlayıcı kullanmak, bu tür nadir durumlarda tam amacın belirtilmesine olanak tanır. Özniteliği[ExampleAttribute]
belirsiz değildir (yine de ! adlıExampleAttributeAttribute
bir öznitelik sınıfı varsa olabilir). SınıfınExample
bildirimi kaldırılırsa, her iki öznitelik de adlıExampleAttribute
öznitelik sınıfına aşağıdaki gibi başvurur:[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 {}
son örnek
Aynı varlıkta birden çok kez tek kullanımlık öznitelik sınıfı kullanmak derleme zamanı hatasıdır.
Örnek: Örnek
[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 {}
, tek kullanımlık bir öznitelik sınıfı olan ve bildiriminde birden çok kez kullanmaya
HelpString
çalıştığından derleme zamanı hatasıylaClass1
sonuçlanır.son örnek
E
İfade, aşağıdaki deyimlerin tümü doğruysa bir attribute_argument_expression:
- türü
E
bir öznitelik parametre türüdür (§22.2.4). - Derleme zamanında değeri
E
aşağıdakilerden biriyle çözülebilir:- Sabit bir değer.
- Genel
System.Type
olmayan bir tür, kapalı bir yapılı tür (§8.4.3) veya ilişkisiz genel tür (§8.4.4) belirten bir typeof_expression (§12.8.18) kullanılarak alınan ancak açık bir tür (§8.4.3) olmayan bir nesne. - attribute_argument_expressiontek boyutlu bir dizi.
Örnek:
[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; }
son örnek
Birden çok bölümde bildirilen bir türün öznitelikleri, her bir parçasının öznitelikleri belirtilmemiş bir sırada birleştirilerek belirlenir. Aynı öznitelik birden çok bölüme yerleştirilirse, bu özniteliğin türünde birden çok kez belirtilmesiyle eşdeğerdir.
Örnek: İki bölüm:
[Attr1, Attr2("hello")] partial class A {} [Attr3, Attr2("goodbye")] partial class A {}
aşağıdaki tek bildirimle eşdeğerdir:
[Attr1, Attr2("hello"), Attr3, Attr2("goodbye")] class A {}
son örnek
Tür parametrelerindeki öznitelikler aynı şekilde birleştirilir.
22.4 Öznitelik örnekleri
22.4.1 Genel
Öznitelik örneği, çalışma zamanında özniteliği temsil eden bir örnektir. Öznitelik, öznitelik sınıfı, konumsal bağımsız değişkenler ve adlandırılmış bağımsız değişkenlerle tanımlanır. Öznitelik örneği, konumsal ve adlandırılmış bağımsız değişkenlerle başlatılan öznitelik sınıfının bir örneğidir.
Bir öznitelik örneğinin alınması, aşağıdaki alt dallarda açıklandığı gibi hem derleme zamanı hem de çalışma zamanı işlemeyi içerir.
22.4.2 Özniteliğin derlenmesi
E
derlemesi, aşağıdaki adımlar aracılığıyla bir derlemede A
derlenir:
- Yeni formun object_creation_expression
T(P)
derlemek için derleme zamanı işleme adımlarını izleyin. Bu adımlar derleme zamanı hatasına neden olur veya çalışmaC
zamanında çağrılabilecek bir örnek oluşturucuyuT
belirler. - Genel erişilebilirliği yoksa
C
derleme zamanı hatası oluşur. - içindeki her
Arg
N
için:- named_argument
Name
tanımlayıcısıArg
-
Name
üzerinde statik olmayan bir okuma-yazma ortak alanı veya özelliği tanımlayacaktırT
. Böyle bir alan veya özellik yoksaT
derleme zamanı hatası oluşur.
- named_argument
- positional_argument_list
System.String
Not: Örnek olarak, düşük vekil kod birimi tarafından hemen takip edilmeyen yüksek vekil UTF-16 kod birimi içeren bir dize iyi biçimlendirilmemiştir. son not
- Özniteliğini içeren programın derlenmesi sonucunda derleyici tarafından derleme çıkışında aşağıdaki bilgileri depolayın: öznitelik sınıfı
T
, üzerindekiC
örnek oluşturucusuT
,P
, named_argument_listN
ve ilişkili program varlığıE
, değerleri derleme zamanında tamamen çözümlenir.
22.4.3 Öznitelik örneğinin çalışma zamanı alımı
§22.4.2'de tanımlanan terimler kullanılarak, , T
, C
ve ile temsil edilen P
ve N
ile E
ilişkilendirilmiş öznitelik örneği aşağıdaki adımlar kullanılarak derlemeden A
çalışma zamanında alınabilir:
- derleme zamanında belirlenen örnek oluşturucusunu ve değerleri kullanarak formunun
new T(P)
birC
yürütmek için çalışma zamanı işleme adımlarını izleyin. Bu adımlar bir özel durumla sonuçlanır veya örneğiniO
T
oluşturur. - içindeki her
Arg
N
sırayla:- named_argument
Name
tanımlayıcısıArg
Name
üzerindeO
statik olmayan bir genel okuma-yazma alanı veya özelliği tanımlamazsa, bir özel durum oluşturulur. - öğesinin attribute_argument_expression değerlendirmenin
Value
sonucu olsunArg
. - üzerinde
Name
bir alan tanımlarsaO
, bu alanı olarakValue
ayarlayın. - Aksi takdirde, Name üzerinde
O
bir özellik tanımlar. Bu özelliği Değer olarak ayarlayın. - Sonuç, öznitelik sınıfının positional_argument_list ve
O
T
named_argument_listP
başlatılan bir örneğidir.N
- named_argument
Not: içinde , ,
T
C
,P
(ve ileN
ilişkilendirilen )E
ve belirtip almaA
E
T
C
P
mekanizmasınıN
depolamaA
biçimi ( ve bu nedenle bir öznitelik örneğinin çalışma zamanında nasıl elde edilir) bu belirtim kapsamı dışındadır. son not
Örnek: CLI'nın bir uygulamasında,
Help
örnek program §22.2.3'te derlenerek oluşturulan derlemedeki öznitelik örnekleri aşağıdaki programla alınabilir:public sealed class InterrogateHelpUrls { public static void Main(string[] args) { Type helpType = typeof(HelpAttribute); string assemblyName = args[0]; foreach (Type t in Assembly.Load(assemblyName).GetTypes()) { Console.WriteLine($"Type : {t}"); var attributes = t.GetCustomAttributes(helpType, false); var helpers = (HelpAttribute[]) attributes; foreach (var helper in helpers) { Console.WriteLine($"\tUrl : {helper.Url}"); } } } }
son örnek
22.5 Ayrılmış öznitelikler
22.5.1 Genel
Bir dizi öznitelik, dili bir şekilde etkiler. Bu öznitelikler arasında şunlar yer alır:
-
System.AttributeUsageAttribute
(§22.5.2), bir öznitelik sınıfının hangi yollarla kullanılabileceğini açıklamak için kullanılır. -
System.Diagnostics.ConditionalAttribute
(§22.5.3), koşullu yöntemleri ve koşullu öznitelik sınıflarını tanımlamak için kullanılan çok kullanımlı bir öznitelik sınıfıdır. Bu öznitelik, koşullu derleme simgesini test ederek bir koşulu gösterir. -
System.ObsoleteAttribute
(§22.5.4), bir üyeyi eski olarak işaretlemek için kullanılır. -
System.Runtime.CompilerServices.AsyncMethodBuilderAttribute
(§22.5.5), zaman uyumsuz bir yöntem için görev oluşturucu oluşturmak için kullanılır. -
System.Runtime.CompilerServices.CallerLineNumberAttribute
(§22.5.6.2),System.Runtime.CompilerServices.CallerFilePathAttribute
(§22.5.6.3) veSystem.Runtime.CompilerServices.CallerMemberNameAttribute
(§22.5.6.4), isteğe bağlı parametrelere çağrı bağlamı hakkında bilgi sağlamak için kullanılır.
Null atanabilir statik analiz öznitelikleri (§22.5.7), null değerler ve null durumlar için oluşturulan uyarıların doğruluğunu iyileştirebilir (§8.9.5).
Yürütme ortamı, C# programının yürütülmesini etkileyen ek uygulama tanımlı öznitelikler sağlayabilir.
22.5.2 AttributeUsage özniteliği
özniteliği AttributeUsage
, öznitelik sınıfının nasıl kullanılabileceğini açıklamak için kullanılır.
özniteliğiyle AttributeUsage
süslenen bir sınıf, doğrudan veya dolaylı olarak öğesinden System.Attribute
türetilir. Aksi takdirde derleme zamanı hatası oluşur.
Not: Bu özniteliği kullanma örneği için bkz . §22.2.2. son not
22.5.3 Koşullu öznitelik
22.5.3.1 Genel
özniteliğiConditional
, koşullu yöntemlerin ve koşullu öznitelik sınıflarının tanımını etkinleştirir.
22.5.3.2 Koşullu yöntemler
özniteliğiyle Conditional
dekore edilmiş bir yöntem, koşullu bir yöntemdir. Bu nedenle her koşullu yöntem, özniteliklerinde Conditional
bildirilen koşullu derleme simgeleriyle ilişkilendirilir.
Örnek:
class Eg { [Conditional("ALPHA")] [Conditional("BETA")] public static void M() { // ... } }
Eg.M
iki koşullu derleme simgesiALPHA
veBETA
ile ilişkili bir koşullu yöntem olarak bildirir.son örnek
Koşullu yönteme yapılan çağrı, ilişkili koşullu derleme simgelerinden biri veya daha fazlası çağrı noktasında tanımlanırsa dahil edilir, aksi takdirde çağrı atlanır.
Koşullu yöntem aşağıdaki kısıtlamalara tabidir:
- Koşullu yöntem, class_declaration veya struct_declaration bir yöntem olmalıdır. Öznitelik bir arabirim bildirimindeki
Conditional
bir yöntemde belirtilirse derleme zamanı hatası oluşur. - Koşullu yöntem dönüş türüne
void
sahip olmalıdır. - Koşullu yöntem değiştirici ile
override
işaretlenmez. Ancak, koşullu bir yöntem değiştirici ilevirtual
işaretlenebilir. Böyle bir yöntemin geçersiz kılmaları örtük olarak koşullu olur ve açıkça birConditional
öznitelikle işaretlenmez. - Koşullu yöntem bir arabirim yönteminin uygulaması olmamalıdır. Aksi takdirde derleme zamanı hatası oluşur.
- Koşullu yöntemin parametreleri çıkış parametreleri olmamalıdır.
Ayrıca, koşullu bir yöntemden temsilci oluşturulursa derleme zamanı hatası oluşur.
Örnek: Örnek
#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(); } }
Class1.M
koşullu bir yöntem olarak bildirir.Class2
'sTest
yöntemi bu yöntemi çağırır. Koşullu derleme simgesiDEBUG
tanımlandığından çağrılırsaClass2.Test
çağrısıM
yapılır. SimgeDEBUG
tanımlanmamışsa çağrısıClass2.Test
Class1.M
yapılmaz.son örnek
Koşullu bir yönteme yapılan çağrının eklenmesinin veya dışlanmasının, çağrının noktasındaki koşullu derleme sembolleri tarafından denetlendiğini anlamak önemlidir.
Örnek: Aşağıdaki kodda
// 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 } }
sınıfları
Class2
veClass3
her biri, tanımlanıp tanımlanmadığınaClass1.F
bağlı olarak koşullu olan koşullu yöntemineDEBUG
çağrılar içerir. Bu simge bağlamındaClass2
tanımlandığından ancak tanımlanmadığındanClass3
, içindeki çağrısıF
Class2
eklenirken içindeki çağrısıF
Class3
atlanır.son örnek
Devralma zincirinde koşullu yöntemlerin kullanılması kafa karıştırıcı olabilir. biçiminden base
aracılığıyla base.M
koşullu bir yönteme yapılan çağrılar, normal koşullu yöntem çağrı kurallarına tabidir.
Örnek: Aşağıdaki kodda
// 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 } }
Class2
, temel sınıfında tanımlanan öğesineM
bir çağrı içerir. Temel yöntem tanımsız olan simgesininDEBUG
varlığına bağlı olarak koşullu olduğundan bu çağrı atlanır. Bu nedenle, yöntemi yalnızca "Class2.M executed
" konsoluna yazar. pp_declaration'ların judicious kullanımı bu tür sorunları ortadan kaldırabilir.son örnek
22.5.3.3 Koşullu öznitelik sınıfları
Bir veya daha fazla öznitelikle süslenmiş bir öznitelik sınıfı (Conditional
), koşullu öznitelik sınıfıdır. Bu nedenle bir koşullu öznitelik sınıfı, özniteliklerinde Conditional
bildirilen koşullu derleme simgeleriyle ilişkilendirilir.
Örnek:
[Conditional("ALPHA")] [Conditional("BETA")] public class TestAttribute : Attribute {}
TestAttribute
, veALPHA
koşullu derleme simgeleriyleBETA
ilişkili bir koşullu öznitelik sınıfı olarak bildirir.son örnek
Koşullu özniteliğin öznitelik belirtimleri (§22.3), ilişkili koşullu derleme simgelerinden biri veya daha fazlası belirtim noktasında tanımlandığında dahil edilir, aksi takdirde öznitelik belirtimi atlanır.
Koşullu öznitelik sınıfının öznitelik belirtiminin eklenmesinin veya dışlanmasının belirtim noktasındaki koşullu derleme simgeleri tarafından denetlendiğini unutmayın.
Örnek: Örnekte
// 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 {}
ve sınıflarının
Class1
her biri, tanımlanıp tanımlanmadığınaClass2
bağlı olarak koşullu olan özniteliğiyleTest
dekoreDEBUG
edilmiştir. Bu simge bağlamındaClass1
tanımlandığından ancak tanımlanmadığındanClass2
, üzerindekiClass1
Test özniteliğinin belirtimi dahil edilirken özniteliğinTest
Class2
belirtimi atlanır.son örnek
22.5.4 Eski öznitelik
özniteliği Obsolete
, artık kullanılmaması gereken türleri ve türlerin üyelerini işaretlemek için kullanılır.
Bir program Obsolete
özniteliğiyle dekore edilmiş bir tür veya üye kullanıyorsa, derleyici bir uyarı veya hata yayınlar. Özellikle, bir derleyici hata parametresi sağlanmazsa veya hata parametresi sağlanıp false
değerine sahipse bir uyarı verir. Hata parametresi belirtilirse ve değeri true
olduğunda derleyici bir hata verir.
Örnek: Aşağıdaki kodda
[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(); } }
sınıfı
A
özniteliğiyleObsolete
dekore edilmiştir. 'ninA
Main
her kullanımı, belirtilen iletiyi içeren bir uyarıyla sonuçlanır: "Bu sınıf eski; yerine sınıfınıB
kullanın".son örnek
22.5.5 AsyncMethodBuilder özniteliği
Bu öznitelik §15.15.1'de açıklanmıştır.
22.5.6 Caller-info öznitelikleri
22.5.6.1 Genel
Günlüğe kaydetme ve raporlama gibi amaçlar için, bazen işlev üyesinin çağıran kod hakkında belirli derleme zamanı bilgilerini alması yararlı olabilir. Çağıran-bilgi öznitelikleri, bu tür bilgileri saydam bir şekilde geçirmek için bir yol sağlar.
İsteğe bağlı bir parametre çağıran-bilgi özniteliklerinden biriyle eklendiğinde, bir çağrıda karşılık gelen bağımsız değişkenin atlanması varsayılan parametre değerinin yerinin alınmasına neden olmaz. Bunun yerine, çağrı bağlamı hakkında belirtilen bilgiler varsa, bu bilgiler bağımsız değişken değeri olarak geçirilir.
Örnek:
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); }
Bağımsız değişken içermeyen bir çağrısı
Log()
, çağrının satır numarasını ve dosya yolunun yanı sıra çağrının gerçekleştiği üyenin adını yazdırır.son örnek
Caller-info öznitelikleri, temsilci bildirimleri de dahil olmak üzere isteğe bağlı parametrelerde her yerde oluşabilir. Ancak, belirli caller-info özniteliklerinin öznitelikleri, ilişkilendirebilecekleri parametre türleri üzerinde kısıtlamalara sahiptir, böylece her zaman yerine alınan bir değerden parametre türüne örtük bir dönüştürme olur.
Kısmi yöntem bildiriminin hem tanımlama hem de uygulama bölümünün parametresinde aynı caller-info özniteliğine sahip olmak bir hatadır. Yalnızca tanımlama bölümündeki caller-info öznitelikleri uygulanırken, yalnızca uygulayan bölümde oluşan caller-info öznitelikleri yoksayılır.
Çağıran bilgileri aşırı yükleme çözümlemesini etkilemez. Öznitelikli isteğe bağlı parametreler çağıranın kaynak kodundan atlandığından aşırı yükleme çözümlemesi, atlanan diğer isteğe bağlı parametreleri (§12.6.4) yoksaydığı gibi bu parametreleri de yoksayar.
Çağıran bilgileri yalnızca bir işlev kaynak kodunda açıkça çağrıldığında değiştirilir. Örtük üst oluşturucu çağrıları gibi örtük çağrıların kaynak konumu yoktur ve arayan bilgilerini değiştirmez. Ayrıca, dinamik olarak bağlı olan çağrılar arayan bilgilerini değiştirmez. Bu gibi durumlarda caller-info öznitelikli bir parametre atlandığında, bunun yerine parametrenin belirtilen varsayılan değeri kullanılır.
Bir özel durum sorgu ifadeleridir. Bunlar söz dizimsel genişletmeler olarak kabul edilir ve genişlettikleri çağrılar, arayan-bilgi öznitelikleriyle isteğe bağlı parametreleri atlayacak şekilde genişletilirse, arayan bilgilerinin yerini alır. Kullanılan konum, çağrının oluşturulduğu sorgu yan tümcesinin konumudur.
Belirli bir parametrede birden fazla caller-info özniteliği belirtilirse, bunlar şu sırayla tanınır: CallerLineNumber
, , CallerFilePath
CallerMemberName
. Aşağıdaki parametre bildirimini göz önünde bulundurun:
[CallerMemberName, CallerFilePath, CallerLineNumber] object p = ...
CallerLineNumber
öncelik alır ve diğer iki öznitelik yoksayılır. Atlanırsa CallerLineNumber
öncelik CallerFilePath
kazanır ve CallerMemberName
yoksayılır. Bu özniteliklerin sözcük temelli sıralaması ilgisizdir.
22.5.6.2 CallerLineNumber özniteliği
Sabit değerden System.Runtime.CompilerServices.CallerLineNumberAttribute
parametrenin türüne standart bir örtük dönüştürme (§10.4.2) olduğunda isteğe bağlı parametrelerde özniteliğine int.MaxValue
izin verilir. Bu, bu değere kadar olan negatif olmayan herhangi bir satır numarasının hatasız geçirilmesini sağlar.
Kaynak kodundaki bir konumdan gelen bir işlev çağrısı, ile isteğe bağlı bir parametreyi CallerLineNumberAttribute
atlarsa, varsayılan parametre değeri yerine çağrıya bağımsız değişken olarak bu konumun satır numarasını temsil eden sayısal sabit değer kullanılır.
Çağrı birden çok satıra yayılıyorsa, seçilen satır uygulamaya bağımlıdır.
Satır numarası yönergelerden #line
etkilenebilir (§6.5.8).
22.5.6.3 CallerFilePath özniteliği
Parametresinin türünden standart örtük dönüştürme (System.Runtime.CompilerServices.CallerFilePathAttribute
) olduğunda isteğe bağlı parametrelerde özniteliğine string
izin verilir.
Kaynak kodundaki bir konumdan yapılan işlev çağrısı, ile isteğe bağlı bir parametreyi CallerFilePathAttribute
atlarsa, bu konumun dosya yolunu temsil eden bir dize sabit değeri, varsayılan parametre değeri yerine çağrıya bağımsız değişken olarak kullanılır.
Dosya yolunun biçimi uygulamaya bağlıdır.
Dosya yolu yönergelerden etkilenebilir #line
(§6.5.8).
22.5.6.4 CallerMemberName özniteliği
Parametresinin türünden standart örtük dönüştürme (System.Runtime.CompilerServices.CallerMemberNameAttribute
) olduğunda isteğe bağlı parametrelerde özniteliğine string
izin verilir.
İşlev üyesinin gövdesindeki bir konumdan veya işlev üyesinin kendisine veya dönüş türüne uygulanan bir öznitelik içindeki bir işlev çağrısı, kaynak kodundaki parametreler veya tür parametreleri ile CallerMemberNameAttribute
isteğe bağlı bir parametreyi atlarsa, bu üyenin adını temsil eden bir dize sabit değeri, varsayılan parametre değeri yerine çağrıya bağımsız değişken olarak kullanılır.
Genel yöntemler içinde gerçekleşen çağrılar için, tür parametre listesi olmadan yalnızca yöntem adı kullanılır.
Açık arabirim üyesi uygulamalarında gerçekleşen çağrılar için, önceki arabirim niteliği olmadan yalnızca yöntem adı kullanılır.
Özellik veya olay erişimcileri içinde gerçekleşen çağrılar için, kullanılan üye adı özelliğin veya olayın kendisidir.
Dizin oluşturucu erişimcileri içinde gerçekleşen çağrılar için, kullanılan üye adı, varsa dizin oluşturucu üyesinde (§22.6Item
Alan veya olay başlatıcılar içinde gerçekleşen çağrılar için, kullanılan üye adı başlatılmakta olan alanın veya olayın adıdır.
Örnek oluşturucularının, statik oluşturucuların, sonlandırıcıların ve işleçlerin bildirimleri içinde gerçekleşen çağrılar için, kullanılan üye adı uygulamaya bağlıdır.
22.5.7 Kod analizi öznitelikleri
22.5.7.1 Genel
Bu bölümdeki öznitelikler, null atanabilirlik ve null durum tanılaması (§8.9.5) sağlayan bir derleyiciyi desteklemek için ek bilgi sağlamak için kullanılır. Derleyicinin null durum tanılaması gerçekleştirmesi gerekmez. Bu özniteliklerin varlığı veya yokluğu, bir programın dilini veya davranışını etkilemez. Null durum tanılaması sağlamayan bir derleyici bu özniteliklerin varlığını okuyup yoksayacaktır. Null durum tanılaması sağlayan bir derleyici, tanılamalarını bilgilendirmek için kullandığı bu özniteliklerden herhangi biri için bu bölümde tanımlanan anlamı kullanacaktır.
Kod analizi öznitelikleri ad alanında System.Diagnostics.CodeAnalysis
bildirilir.
Öznitelik | Anlamı |
---|---|
AllowNull (§22.5.7.2) |
Null değer atanamayan bir bağımsız değişken null olabilir. |
DisallowNull (§22.5.7.3) |
Boş değer atanabilir bağımsız değişken hiçbir zaman null olmamalıdır. |
MaybeNull (§22.5.7.6) |
Null değer atanamayan bir dönüş değeri null olabilir. |
NotNull (§22.5.7.8) |
Null değer atanabilir dönüş değeri hiçbir zaman null olmaz. |
MaybeNullWhen (§22.5.7.7) |
Yöntem belirtilen bool değeri döndürdüğünde null değer atanamayan bir bağımsız değişken null olabilir. |
NotNullWhen (§22.5.7.10) |
Yöntem belirtilen bool değeri döndürdüğünde null atanabilir bağımsız değişken null olmaz. |
NotNullIfNotNull (§22.5.7.9) |
Belirtilen parametrenin bağımsız değişkeni null değilse, dönüş değeri null değildir. |
DoesNotReturn (§22.5.7.4) |
Bu yöntem hiçbir zaman döndürmez. |
DoesNotReturnIf (§22.5.7.5) |
İlişkili bool parametre belirtilen değere sahipse bu yöntem hiçbir zaman döndürmez. |
Aşağıdaki §22.5.7.1 bölümleri koşullu olarak normatiftir.
22.5.7.2 AllowNull özniteliği
Karşılık gelen tür izin vermese bile giriş olarak null değere izin verildiğini belirtir.
Örnek: Makul bir varsayılan değere sahip olduğundan hiçbir zaman döndürülmemiş
null
aşağıdaki okuma/yazma özelliğini göz önünde bulundurun. Ancak, bir kullanıcı özelliği bu varsayılan değere ayarlamak için küme erişimcisine null verebilir.#nullable enable public class X { [AllowNull] public string ScreenName { get => _screenName; set => _screenName = value ?? GenerateRandomScreenName(); } private string _screenName = GenerateRandomScreenName(); private static string GenerateRandomScreenName() => ...; }
Bu özelliğin küme erişimcisinin aşağıdaki kullanımı göz önünde bulundurulduğunda
var v = new X(); v.ScreenName = null; // may warn without attribute AllowNull
Özniteliği olmadan, null kabul etmeyen türdeki özellik null değere ayarlanmış gibi göründüğü için derleyici bir uyarı oluşturabilir. özniteliğinin varlığı bu uyarıyı bastırır. son örnek
22.5.7.3 DisallowNull özniteliği
Karşılık gelen tür izin verse bile giriş olarak null değere izin verilmediğini belirtir.
Örnek: Null değerinin varsayılan değer olduğu ancak istemcilerin bunu yalnızca null olmayan bir değere ayarlayabildiği aşağıdaki özelliği göz önünde bulundurun.
#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; }
Get erişimcisi varsayılan
null
değerini döndürebileceğinden, derleyici erişimden önce denetlenmesi gerektiği konusunda uyarabilir. Ayrıca çağıranları null olsa da çağıranların bunu açıkça null olarak ayarlamaması gerektiği konusunda uyarır. son örnek
22.5.7.4 DoNotReturn özniteliği
Belirli bir yöntemin hiçbir zaman döndürmediğini belirtir.
Örnek: Aşağıdakileri göz önünde bulundurun:
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; }
özniteliğinin varlığı bir derleyiciye çeşitli yollarla yardımcı olur. İlk olarak, yöntemin özel durum oluşturmadan çıkabileceği bir yol varsa, derleyici bir uyarı verebilir. İkinci olarak, derleyici uygun bir catch bloğu bulunana kadar bu yönteme yapılan çağrıdan sonra herhangi bir kodda null olabilir uyarılarını bastırabilir. Üçüncüsü, erişilemeyen kod hiçbir null durumu etkilemez.
Öznitelik, bu özniteliğin varlığına bağlı olarak erişilebilirliği (§13.2) veya kesin atama (§9.4) analizini değiştirmez. Yalnızca null atanabilirlik uyarılarını etkilemek için kullanılır. son örnek
22.5.7.5 DoNotReturnIf özniteliği
İlişkili bool
parametre belirtilen değere sahipse, belirli bir yöntemin hiçbir zaman döndürülmeyeceğini belirtir.
Örnek: Aşağıdakileri göz önünde bulundurun:
#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!; }
son örnek
22.5.7.6 MaybeNull özniteliği
Null değer atanamayan bir dönüş değerinin null olabileceğini belirtir.
Örnek: Aşağıdaki genel yöntemi göz önünde bulundurun:
#nullable enable public T? Find<T>(IEnumerable<T> sequence, Func<T, bool> predicate) { ... }
Bu kodun fikri, ile
T
string
değiştirilirseT?
null atanabilir bir ek açıklamaya dönüşüyor olmasıdır. Ancak, bu kod bir başvuru türü olarak kısıtlanmadığından yasalT
değildir. Ancak, bu özniteliğin eklenmesi sorunu çözer:#nullable enable [return: MaybeNull] public T Find<T>(IEnumerable<T> sequence, Func<T, bool> predicate) { ... }
özniteliği, çağıranlara sözleşmenin null atanamaz bir tür anlamına geldiğini bildirir, ancak dönüş değeri aslında olabilir
null
. son örnek
22.5.7.7 MaybeNullWhen özniteliği
Yöntemin belirtilen null
değeri döndürdüğünde null atanamaz bir bağımsız değişkenin olabileceğini bool
belirtir. Bu, özniteliğine MaybeNull
benzer (§22.5.7.6), ancak belirtilen dönüş değeri için bir parametre içerir.
22.5.7.8 NotNull özniteliği
Yöntemin döndürdüğünde (oluşturma yerine) null atanabilir değerin hiçbir zaman olacağını null
belirtir.
Örnek: Aşağıdakileri göz önünde bulundurun:
#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); }
Null başvuru türleri etkinleştirildiğinde, yöntem
ThrowWhenNull
uyarı olmadan derlenir. Bu yöntem döndürdüğünde bağımsız değişkenininvalue
olmamasınull
garanti edilir. Ancak null başvuruyla çağrıThrowWhenNull
yapmak kabul edilebilir. son örnek
22.5.7.9 NotNullIfNotNull özniteliği
Belirtilen parametrenin bağımsız değişkeni değilse null
bir dönüş değerinin olmadığını null
belirtir.
Örnek: Dönüş değerinin null durumu, bir veya daha fazla bağımsız değişkenin null durumuna bağlı olabilir. Belirli bağımsız değişkenler
null
olmadığında ve bir yöntem her zaman null olmayan bir değer döndürdüğünde derleyici analizine yardımcı olmak içinNotNullIfNotNull
özniteliği kullanılabilir. Aşağıdaki yöntemi göz önünde bulundurun:#nullable enable string GetTopLevelDomainFromFullUrl(string url) { ... }
url
Bağımsız değişken değilsenull
null
döndürülemez. Null atanabilir başvurular etkinleştirildiğinde, API hiçbir zaman null bağımsız değişken kabul etmemesi koşuluyla bu imza düzgün çalışır. Ancak, bağımsız değişken null olabilirse, dönüş değeri de null olabilir. Bu sözleşmeyi doğru ifade etmek için bu yönteme aşağıdaki şekilde açıklama ekleyin:#nullable enable [return: NotNullIfNotNull("url")] string? GetTopLevelDomainFromFullUrl(string? url) { ... }
son örnek
22.5.7.10 NotNullWh özniteliği
Yöntem belirtilen null
değeri döndürdüğünde null atanabilir bir bağımsız değişkenin olmayacağı bool
belirtir.
Örnek: Kitaplık yöntemi
String.IsNullOrEmpty(String)
, bağımsız değişken boş bir dize olduğundatrue
döndürürnull
. Bu bir null-check biçimidir: Yönteminin döndürdüğündefalse
çağıranların bağımsız değişkeni null olarak denetlemesi gerekmez. Bunun gibi bir yöntemi null atanabilir hale getirmek için parametre türünü null atanabilir bir başvuru türü yapın ve NotNullWhen özniteliğini ekleyin:#nullable enable bool IsNullOrEmpty([NotNullWhen(false)] string? value) { ... }
son örnek
Birlikte çalışma için 22.6 Öznitelikleri
Diğer dillerle birlikte çalışma için dizin oluşturucu dizine alınan özellikler kullanılarak uygulanabilir. Dizin oluşturucu için öznitelik yoksa IndexerName
, ad Item
varsayılan olarak kullanılır. özniteliği, IndexerName
bir geliştiricinin bu varsayılanı geçersiz kılıp farklı bir ad belirtmesini sağlar.
Örnek: Dizin oluşturucu adı varsayılan olarak şeklindedir
Item
. Bu, aşağıdaki gibi geçersiz kılınabilir:[System.Runtime.CompilerServices.IndexerName("TheItem")] public int this[int index] { get { ... } set { ... } }
Dizin oluşturucunun adı şudur:
TheItem
.son örnek
ECMA C# draft specification