Ayrılmış öznitelikler: Çeşitli
Bu öznitelikler kodundaki öğelere uygulanabilir. Bu öğelere anlam anlamları ekler. Derleyici, çıkışını değiştirmek ve geliştiricilerin kodunuzu kullanarak olası hataları bildirmesi için bu anlam anlamlarını kullanır.
Conditional özniteliği
özniteliği, Conditional bir yöntemin yürütülmesini önişleme tanımlayıcısına bağımlı hale gelir. özniteliği, Conditional için bir diğer ConditionalAttribute addır ve bir yönteme veya öznitelik sınıfına uygulanabilir.
Aşağıdaki örnekte, programa Conditional özgü tanılama bilgilerini görüntülemeyi etkinleştirmek veya devre dışı bırakmak için bir yöntem uygulanır:
#define TRACE_ON
using System;
using System.Diagnostics;
namespace AttributeExamples
{
public class Trace
{
[Conditional("TRACE_ON")]
public static void Msg(string msg)
{
Console.WriteLine(msg);
}
}
public class TraceExample
{
public static void Main()
{
Trace.Msg("Now in Main...");
Console.WriteLine("Done.");
}
}
}
Tanımlayıcı TRACE_ON tanımlanmamışsa izleme çıkışı görüntülenmez. Etkileşimli pencerede kendiniz keşfedin.
Özniteliği, aşağıdaki örnekte gösterildiği gibi, genellikle hata ayıklama derlemeleri için izleme ve günlüğe kaydetme özelliklerini etkinleştirmek için tanımlayıcı ile birlikte kullanılır, ancak sürüm Conditional DEBUG derlemeleri içinde kullanılamaz:
[Conditional("DEBUG")]
static void DebugMethod()
{
}
Koşullu olarak işaretlenen bir yöntem çağrıldı olduğunda, belirtilen önişlem simgesinin varlığı veya olmaması, derleyicinin yönteme yapılan çağrıları dahil edip edip elemez olduğunu belirler. Sembol tanımlanmışsa çağrı dahil edilir; aksi takdirde, çağrı atlanır. Koşullu yöntem bir sınıf veya yapı bildiriminde bir yöntem olmalı ve bir dönüş void türüne sahip olması gerekir. kullanımı bloklar içinde kapsayan yöntemlere göre daha temiz, daha zarif Conditional ve daha az hataya karşı daha az #if…#endif hataya neden olur.
Bir yöntemin birden çok özniteliği varsa, derleyici bir veya daha fazla koşullu simge tanımlanmışsa yöntemine çağrılar içerir (simgeler OR işleci kullanılarak mantıksal olarak Conditional birbirine bağlıdır). Aşağıdaki örnekte, veya varlığı bir A B yöntem çağrısıyla sonuç verir:
[Conditional("A"), Conditional("B")]
static void DoIfAorB()
{
// ...
}
Öznitelik Conditional sınıfları ile kullanma
özniteliği Conditional bir öznitelik sınıfı tanımına da uygulanabilir. Aşağıdaki örnekte, özel öznitelik yalnızca Documentation tanımlanmışsa meta verilere bilgi DEBUG ekler.
[Conditional("DEBUG")]
public class DocumentationAttribute : System.Attribute
{
string text;
public DocumentationAttribute(string text)
{
this.text = text;
}
}
class SampleClass
{
// This attribute will only be included if DEBUG is defined.
[Documentation("This method displays an integer.")]
static void DoWork(int i)
{
System.Console.WriteLine(i.ToString());
}
}
Obsolete özniteliği
özniteliği Obsolete bir kod öğesini artık kullanılması önerilmez olarak işaretler. Kullanımdan kaldırılmış olarak işaretlenen bir varlığın kullanımı bir uyarı veya hata üretir. özniteliği Obsolete tek kullanımlık bir özniteliktir ve özniteliklere izin veren herhangi bir varlığa uygulanabilir. Obsolete , için bir diğer ObsoleteAttribute addır.
Aşağıdaki örnekte, özniteliği Obsolete sınıfına ve A yöntemine B.OldMethod uygulanır. uygulanan öznitelik oluşturucusuza ikinci bağımsız değişkeni olarak ayarlanmadan, bu yöntem derleyici hatasına neden B.OldMethod true olurken sınıfını kullanmak yalnızca bir uyarı A üretir. Ancak B.NewMethod çağrısı herhangi bir uyarı veya hata üretmez. Örneğin, önceki tanımlarla birlikte bunu kullanırsanız, aşağıdaki kod iki uyarı ve bir hata üretir:
using System;
namespace AttributeExamples
{
[Obsolete("use class B")]
public class A
{
public void Method() { }
}
public class B
{
[Obsolete("use NewMethod", true)]
public void OldMethod() { }
public void NewMethod() { }
}
public static class ObsoleteProgram
{
public static void Main()
{
// Generates 2 warnings:
A a = new A();
// Generate no errors or warnings:
B b = new B();
b.NewMethod();
// Generates an error, compilation fails.
// b.OldMethod();
}
}
}
Öznitelik oluşturucusu için ilk bağımsız değişken olarak sağlanan dize uyarı veya hatanın bir parçası olarak görüntülenir. Sınıf için iki A uyarı oluşturulur: biri sınıf başvurusu bildirimi için, biri de sınıf oluşturucusu için. özniteliği Obsolete bağımsız değişkenler olmadan kullanılabilir, ancak bunun yerine nelerin kullanılması önerilecek bir açıklama dahil edilir.
C# 10'da, adların eş olduğundan emin olmak için sabit dize nameof ilişkilendirmesi ve işleci kullanabilirsiniz:
public class B
{
[Obsolete($"use {nameof(NewMethod)} instead", true)]
public void OldMethod() { }
public void NewMethod() { }
}
AttributeUsage özniteliği
özniteliği, AttributeUsage özel bir öznitelik sınıfının nasıl kullanıla olacağını belirler. AttributeUsageAttribute , özel öznitelik tanımları için uygulayan bir özniteliktir. özniteliği AttributeUsage şunları denetlemeye olanak sağlar:
- Hangi program öğeleri özniteliğine uygulanabilirsiniz? Kullanımını kısıtlamadıkça, bir öznitelik aşağıdaki program öğelerine uygulanabilir:
- Bütünleştirilmiş Kod
- Modül
- Alan
- Olay
- Yöntem
- Param
- Özellik
- Dönüş
- Tür
- Bir özniteliğin tek bir program öğesine birden çok kez uygulanıp uygulanamayacakları.
- Özniteliklerin türetilmiş sınıflar tarafından devralınıp devralınmay olmadığı.
Varsayılan ayarlar açıkça uygulandığında aşağıdaki örnekteki gibi olur:
[AttributeUsage(AttributeTargets.All,
AllowMultiple = false,
Inherited = true)]
class NewAttribute : Attribute { }
Bu örnekte, NewAttribute sınıfı desteklenen herhangi bir program öğesine uygulanabilir. Ancak her varlığa yalnızca bir kez uygulanabilir. Özniteliği, bir temel sınıfa uygulandığında türetilmiş sınıflar tarafından devralınır.
ve AllowMultiple bağımsız Inherited değişkenleri isteğe bağlıdır, bu nedenle aşağıdaki kod aynı etkiye sahiptir:
[AttributeUsage(AttributeTargets.All)]
class NewAttribute : Attribute { }
İlk AttributeUsageAttribute bağımsız değişken, numaralamanın bir veya daha AttributeTargets fazla öğe olması gerekir. Aşağıdaki örnekte olduğu gibi, or işleciyle birden çok hedef türü birbirine bağlanarak bağlan:
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
class NewPropertyOrFieldAttribute : Attribute { }
C# 7.3'den başerek, öznitelikler otomatik uygulanan bir özelliğin özelliğine veya destek alanına uygulanabilir. Özniteliğin belirteci belirtmedikçe özniteliği field özelliğine uygulanır. Her ikisi de aşağıdaki örnekte gösterilmiştir:
class MyClass
{
// Attribute attached to property:
[NewPropertyOrField]
public string Name { get; set; } = string.Empty;
// Attribute attached to backing field:
[field: NewPropertyOrField]
public string Description { get; set; } = string.Empty;
}
bağımsız değişkeni ise, elde edilen öznitelik aşağıdaki örnekte gösterildiği gibi tek bir varlığa AllowMultiple true birden çok kez uygulanabilir:
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
class MultiUse : Attribute { }
[MultiUse]
[MultiUse]
class Class1 { }
[MultiUse, MultiUse]
class Class2 { }
Bu durumda, MultiUseAttribute olarak ayarlanmış olduğundan tekrar tekrar AllowMultiple true uygulanabilir. Birden çok öznitelik uygulamak için gösterilen her iki biçim de geçerlidir.
ise, Inherited false özniteliği öznitelikli bir sınıftan türetilen sınıflar tarafından devralınmaz. Örnek:
[AttributeUsage(AttributeTargets.Class, Inherited = false)]
class NonInheritedAttribute : Attribute { }
[NonInherited]
class BClass { }
class DClass : BClass { }
Bu NonInheritedAttribute durumda, devralma yoluyla için DClass uygulanmaz.
Bir özniteliğin nereye uygulanması gerektiğini belirtmek için de bu anahtar sözcükleri kullanabilirsiniz. Örneğin, otomatik uygulanan bir özelliğin backing alanına öznitelik field: eklemek için belirleyiciyi kullanabilirsiniz. Ya da konumsal field: property: param: kayıttan oluşturulan öğelerden herhangi biri için bir öznitelik uygulamak için , veya belirleyici kullanabilirsiniz. Bir örnek için özellik tanımı için konumsal söz dizimi'ne bakın.
AsyncMethodBuilder özniteliği
C# 7'den başarak özniteliğini zaman uyumsuz dönüş System.Runtime.CompilerServices.AsyncMethodBuilderAttribute türü olan bir türe eklersiniz. özniteliği, belirtilen tür bir zaman uyumsuz yöntemden döndürül olduğunda zaman uyumsuz yöntem uygulamasını derleme türünü belirtir. özniteliği AsyncMethodBuilder aşağıdaki türlere uygulanabilir:
- Erişilebilir bir yöntemi
GetAwaitervardır. - yöntemi tarafından döndürülen
GetAwaiternesne arabirimini System.Runtime.CompilerServices.ICriticalNotifyCompletion kullanır.
özniteliğinin AsyncMethodBuilder oluşturucusu, ilişkili oluşturucu türünü belirtir. Oluşturucu aşağıdaki erişilebilir üyeleri uygulamalı:
Oluşturucu
Create()türü döndüren statik bir yöntem.Zaman uyumsuz
Taskdönüş türünü döndüren okunabilir bir özellik.Bir
void SetException(Exception)görev hataya neden olduğunda özel durumu ayaran bir yöntem.Görevi
void SetResult()void SetResult(T result)tamamlandı olarak işaretlayan ve isteğe bağlı olarak görevin sonucu ayarlayan veya yöntemiAşağıdaki
StartAPI imzasını kullanan bir yöntem:void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : System.Runtime.CompilerServices.IAsyncStateMachineAşağıdaki
AwaitOnCompletedimzaya sahip bir yöntem:public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : System.Runtime.CompilerServices.INotifyCompletion where TStateMachine : System.Runtime.CompilerServices.IAsyncStateMachineAşağıdaki
AwaitUnsafeOnCompletedimzaya sahip bir yöntem:public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : System.Runtime.CompilerServices.ICriticalNotifyCompletion where TStateMachine : System.Runtime.CompilerServices.IAsyncStateMachine
.NET tarafından sağlanan aşağıdaki oluşturucular hakkında bilgi edinerek zaman uyumsuz yöntem oluşturucuları hakkında bilgi edinebilirsiniz:
- System.Runtime.CompilerServices.AsyncTaskMethodBuilder
- System.Runtime.CompilerServices.AsyncTaskMethodBuilder<TResult>
- System.Runtime.CompilerServices.AsyncValueTaskMethodBuilder
- System.Runtime.CompilerServices.AsyncValueTaskMethodBuilder<TResult>
C# 10 ve sonraki bir içinde özniteliği, oluşturucu türü için geçersiz kılmak üzere zaman uyumsuz AsyncMethodBuilder bir yönteme uygulanabilir.
InterpolatedStringHandler ve InterpolatedStringHandlerArguments öznitelikleri
C# 10'dan başlayarak, bir türün bir i ilişkilendirmeli dize işleyicisi olduğunu belirtmek için bu öznitelikleri kullanırsiniz. .NET 6 kitaplığı, bir parametre için bağımsız değişken olarak System.Runtime.CompilerServices.DefaultInterpolatedStringHandler irdelenmiş dizeyi kullanabileceğiniz senaryolar için zaten string içerir. İlişkili dizelerin nasıl işlenmeyi denetlemeyi istediğiniz başka örnekleri de olabilir. System.Runtime.CompilerServices.InterpolatedStringHandlerAttributeİşleyicinizi uygulayan türe uygulanır. bu System.Runtime.CompilerServices.InterpolatedStringHandlerArgumentAttribute türün oluşturucus un parametrelerine uygulanır.
İlişkili dize geliştirmeleri için C# 10 özellik belirtimsinde irdelenmiş dize işleyicisi oluşturma hakkında daha fazla bilgi öğrenebilirsiniz.
ModuleInitializer özniteliği
C# 9'dan ModuleInitializer başlayarak, öznitelik derleme yüklenirken çalışma zamanının çağıryacağı bir yöntemi işaretler. ModuleInitializer , için bir diğer ModuleInitializerAttribute addır.
özniteliği ModuleInitializer yalnızca şu yöntemlere uygulanabilir:
- Statiktir.
- Parametresiz.
voiddöndürür.- ,, Veya içeren modülünden erişilebilir
internalpublic. - Genel bir yöntem değildir.
- Genel bir sınıfta içerilmiyor.
- Yerel bir işlev değil.
ModuleInitializerÖzniteliği birden çok yönteme uygulanabilir. Bu durumda, çalışma zamanının onları çağıran sıra belirleyici olur ancak belirtilmez.
Aşağıdaki örnekte, birden çok modül başlatıcısı yönteminin kullanımı gösterilmektedir. Init1Ve Init2 yöntemleri daha önce çalışır Main ve her biri özelliğine bir dize ekler Text . Bu nedenle Main , özelliği çalıştırıldığında Text her iki Başlatıcı yönteminden dizeler zaten vardır.
using System;
internal class ModuleInitializerExampleMain
{
public static void Main()
{
Console.WriteLine(ModuleInitializerExampleModule.Text);
//output: Hello from Init1! Hello from Init2!
}
}
using System.Runtime.CompilerServices;
internal class ModuleInitializerExampleModule
{
public static string? Text { get; set; }
[ModuleInitializer]
public static void Init1()
{
Text += "Hello from Init1! ";
}
[ModuleInitializer]
public static void Init2()
{
Text += "Hello from Init2! ";
}
}
Kaynak kodu oluşturanlar bazen başlatma kodu üretmemelidir. Modül başlatıcıları, bu kod için standart bir yer sağlar.
SkipLocalsInit özniteliği
C# 9 ' dan itibaren SkipLocalsInit öznitelik, derleyicinin .locals init meta veriye yayırken bayrak değiştirmesini engeller. SkipLocalsInitÖzniteliği tek kullanılan bir özniteliktir ve bir metoda, özelliğe, bir sınıfa, yapıya, arabirime veya modüle uygulanabilir ancak bir derlemeye uygulanamaz. SkipLocalsInit , için bir diğer addır SkipLocalsInitAttribute .
.locals initBayrak, clr 'nin bir yöntemde belirtilen tüm yerel değişkenleri varsayılan değerlerine başlatmasını sağlar. Derleyici aynı zamanda bir değeri bir değere atamadan önce hiçbir şekilde hiç bir değişken kullandığınızdan emin olduğundan, .locals init genellikle gerekli değildir. Ancak, yığın üzerinde bir dizi ayırmak için stackalloc kullandığınızda gibi, ek sıfır başlatma bazı senaryolarda ölçülebilir performans etkisine sahip olabilir. Bu durumlarda SkipLocalsInit özniteliği ekleyebilirsiniz. Bir yönteme doğrudan uygulanırsa öznitelik, Lambdalar ve yerel işlevler dahil olmak üzere bu yöntemi ve tüm iç içe geçmiş işlevleri etkiler. Bir tür veya modüle uygulanmışsa, içinde iç içe geçmiş tüm yöntemleri etkiler. Bu öznitelik soyut yöntemleri etkilemez, ancak uygulama için oluşturulan kodu etkiler.
Bu öznitelik, AllowUnsafeBlocks derleyici seçeneğini gerektiriyor. Bu gereksinim, bazı durumlarda kod atanmamış belleği (örneğin, başlatılmamış yığına ayrılan bellekten okuma) görüntüleyebileceğinden emin olarak bildirir.
Aşağıdaki örnek, SkipLocalsInit tarafından kullanılan bir yöntemde özniteliğinin etkisini gösterir stackalloc . Bu yöntem, tamsayılar dizisi ayrıldığında bellekte ne olduğunu gösterir.
[SkipLocalsInit]
static void ReadUninitializedMemory()
{
Span<int> numbers = stackalloc int[120];
for (int i = 0; i < 120; i++)
{
Console.WriteLine(numbers[i]);
}
}
// output depends on initial contents of memory, for example:
//0
//0
//0
//168
//0
//-1271631451
//32767
//38
//0
//0
//0
//38
// Remaining rows omitted for brevity.
Bu kodu kendiniz denemek için AllowUnsafeBlocks . csproj dosyanızdaki derleyici seçeneğini ayarlayın:
<PropertyGroup>
...
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>