Aracılığıyla paylaş


Özel öznitelikleri tanımlama ve okuma

Öznitelikler, bilgileri bildirim temelli bir şekilde kodla ilişkilendirmenin bir yolunu sağlar. Ayrıca çeşitli hedeflere uygulanabilen yeniden kullanılabilir bir öğe de sağlayabilirler. ObsoleteAttribute öğesini göz önünde bulundurun. Sınıflara, yapılara, yöntemlere, oluşturuculara ve daha fazlasına uygulanabilir. Öğenin kullanımdan kaldırıldığını bildirir . Daha sonra bu özniteliği aramak ve yanıt olarak bazı eylemler gerçekleştirmek C# derleyicisine bağlı olur.

Bu öğreticide, kodunuza öznitelik eklemeyi, kendi özniteliklerinizi oluşturmayı ve kullanmayı ve .NET'te yerleşik olan bazı öznitelikleri kullanmayı öğreneceksiniz.

Önkoşullar

Makinenizi .NET çalıştıracak şekilde ayarlamanız gerekir. Yükleme yönergelerini .NET İndirmeleri sayfasında bulabilirsiniz. Bu uygulamayı Windows, Ubuntu Linux, macOS veya bir Docker kapsayıcısında çalıştırabilirsiniz. Sık kullandığınız kod düzenleyicisini yüklemeniz gerekir. Aşağıdaki açıklamalarda, açık kaynaklı, platformlar arası bir düzenleyici olan Visual Studio Code kullanılmaktadır. Bununla birlikte, rahatça kullanabileceğiniz araçları kullanabilirsiniz.

Uygulamayı oluşturma

Tüm araçları yüklediğinize göre, yeni bir .NET konsol uygulaması oluşturun. Komut satırı oluşturucusunu kullanmak için, en sevdiğiniz kabukta aşağıdaki komutu çalıştırın:

dotnet new console

Bu komut çıplak kemikli .NET proje dosyaları oluşturur. Bu projeyi derlemek için gereken bağımlılıkları geri yüklemek için komutunu çalıştırırsınız dotnet restore .

dotnet restore, dotnet new, dotnet build, dotnet run, dotnet testve dotnet publishgibi geri yükleme gerektiren tüm komutlar tarafından örtük olarak çalıştırıldığından dotnet pack çalıştırmanız gerekmez. Örtük geri yüklemeyi devre dışı bırakmak için --no-restore seçeneğini kullanın.

komutu, geri yüklemenin anlamlı olduğu bazı senaryolarda hala yararlıdır, örneğin Azure DevOps Services'teki sürekli tümleştirme derlemeleri veya geri yüklemenin ne zaman gerçekleştiğini açıkça kontrol etmesi gereken derleme sistemlerinde.

NuGet akışlarını yönetme hakkında bilgi için belgelerine bakın.

Programı yürütmek için kullanın dotnet run. Konsolda "Hello, World" çıkışını görmeniz gerekir.

Koda öznitelik ekleme

C# dilinde öznitelikler, temel sınıftan Attribute devralan sınıflardır. öğesinden Attribute devralan herhangi bir sınıf, diğer kod parçalarında bir tür "etiket" olarak kullanılabilir. Örneğin, adlı ObsoleteAttributebir öznitelik vardır. Bu öznitelik, kodun kullanımdan kaldırıldığını ve artık kullanılmaması gerektiğini gösterir. Bu özniteliği, örneğin köşeli ayraçları kullanarak bir sınıfa yerleştirirsiniz.

[Obsolete]
public class MyClass
{
}

Sınıf adı olarak ObsoleteAttribute kullanılırken, kodda yalnızca [Obsolete] gereklidir. C# kodunun çoğu bu kuralı izler. İsterseniz tam adı [ObsoleteAttribute] kullanabilirsiniz.

Bir sınıfı kullanımdan kaldırılmış olarak işaretlerken, bunun neden kullanım dışı olduğuna ve/veya bunun yerine ne kullanılacağına dair bazı bilgiler sağlamak iyi bir fikirdir. Bu açıklamayı sağlamak için Eski özniteliğine bir dize parametresi eklersiniz.

[Obsolete("ThisClass is obsolete. Use ThisClass2 instead.")]
public class ThisClass
{
}

Dize, ObsoleteAttribute oluşturucusuna, sanki var attr = new ObsoleteAttribute("some string") yazıyormuşsunuz gibi, bağımsız değişken olarak geçiriliyor.

Öznitelik oluşturucusunun parametreleri basit türler/değişmez değerlerle sınırlıdır: bool, int, double, string, Type, enums, etc ve bu türlerin dizileri. İfade veya değişken kullanamazsınız. Konumsal veya adlandırılmış parametreleri kullanabilirsiniz.

Kendi özniteliğinizi oluşturma

Temel sınıftan Attribute devralan yeni bir sınıf tanımlayarak bir öznitelik oluşturursunuz.

public class MySpecialAttribute : Attribute
{
}

Önceki kodla, kod tabanının başka bir yerinde öznitelik olarak [MySpecial] (veya [MySpecialAttribute]) kullanabilirsiniz.

[MySpecial]
public class SomeOtherClass
{
}

.NET temel sınıf kitaplığındaki öznitelikler, derleyici içinde belirli davranışları tetikler. Ancak, oluşturduğunuz herhangi bir öznitelik yalnızca meta veri işlevi görür ve öznitelik sınıfındaki herhangi bir kodun yürütülmesine neden olmaz. Bu meta veriler üzerinde kodunuzun başka bir yerinde işlem yapmak size bağlıdır.

Burada dikkat edilmesi gereken bir tuzak var. Daha önce belirtildiği gibi, öznitelikler kullanılırken yalnızca bazı türler bağımsız değişken olarak geçirilebilir. Ancak, bir öznitelik türü oluştururken C# derleyicisi bu parametreleri oluşturmanızı engellemez. Aşağıdaki örnekte, doğru şekilde derlenen bir oluşturucu ile bir öznitelik oluşturdunuz.

public class GotchaAttribute : Attribute
{
    public GotchaAttribute(Foo myClass, string str)
    {
    }
}

Ancak, bu oluşturucuyu öznitelik söz dizimi ile kullanamazsınız.

[Gotcha(new Foo(), "test")] // does not compile
public class AttributeFail
{
}

Yukarıdaki kod aşağıdaki gibi bir derleyici hatasına neden olur: Attribute constructor parameter 'myClass' has type 'Foo', which is not a valid attribute parameter type

Öznitelik kullanımını kısıtlama

Öznitelikler aşağıdaki "hedeflerde" kullanılabilir. Yukarıdaki örnekler bunları sınıflarda gösterir, ancak şunlarda da kullanılabilir:

  • Meclis
  • Sınıf
  • Yapıcı
  • Temsilci
  • enum
  • Etkinlik
  • Alan
  • GenelParametre
  • Arayüz
  • Yöntem
  • Modül
  • Parametre
  • Mülkiyet
  • Dönüş Değeri
  • Yapı

Bir öznitelik sınıfı oluşturduğunuzda, varsayılan olarak C# bu özniteliği olası öznitelik hedeflerinden herhangi birinde kullanmanıza olanak tanır. Özniteliğinizi belirli hedeflerle kısıtlamak istiyorsanız, bunu öznitelik sınıfınızda kullanarak AttributeUsageAttribute yapabilirsiniz. Bu doğru, özniteliğin üstünde bir öznitelik!

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)]
public class MyAttributeForClassAndStructOnly : Attribute
{
}

Yukarıdaki özniteliği sınıf veya yapı olmayan bir şeye yerleştirmeye çalışırsanız, aşağıdaki gibi bir derleyici hatası alırsınız: Attribute 'MyAttributeForClassAndStructOnly' is not valid on this declaration type. It is only valid on 'class, struct' declarations

public class Foo
{
    // if the below attribute was uncommented, it would cause a compiler error
    // [MyAttributeForClassAndStructOnly]
    public Foo()
    { }
}

Kod öğesine eklenmiş öznitelikleri kullanma

Öznitelikler meta veri görevi görür. Dışa doğru bir güç olmadan hiçbir şey yapmazlar.

Öznitelikleri bulmak ve üzerinde işlem yapmak için yansıma gerekir. Yansıma, C# dilinde diğer kodu inceleyen kod yazmanızı sağlar. Örneğin, bir sınıf hakkında bilgi almak için Yansıma'yı kullanabilirsiniz (kodunuzun başına ekleyin using System.Reflection; ):

TypeInfo typeInfo = typeof(MyClass).GetTypeInfo();
Console.WriteLine("The assembly qualified name of MyClass is " + typeInfo.AssemblyQualifiedName);

Bu, aşağıdaki gibi bir şey yazdırır: The assembly qualified name of MyClass is ConsoleApplication.MyClass, attributes, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null

Bir TypeInfo nesnesine (veya bir MemberInfo, FieldInfo veya başka bir nesneye) sahip olduktan sonra GetCustomAttributes yöntemini kullanabilirsiniz. Bu yöntem bir nesne koleksiyonu Attribute döndürür. Ayrıca bir Öznitelik türü de kullanabilir GetCustomAttribute ve belirtebilirsiniz.

Burada, GetCustomAttributes'yi MemberInfo örneğinde kullanma örneği verilmiştir (daha önce gördüğümüz MyClass örneğin üzerinde bir [Obsolete] özniteliği vardı).

var attrs = typeInfo.GetCustomAttributes();
foreach(var attr in attrs)
    Console.WriteLine("Attribute on MyClass: " + attr.GetType().Name);

Konsolda şu görüntülenir: Attribute on MyClass: ObsoleteAttribute. Başka öznitelikler eklemeyi MyClass öğesine deneyin.

Bu Attribute nesnelerin tembel bir şekilde oluşturulduğunu unutmayın. Yani, GetCustomAttribute veya GetCustomAttributes kullanana kadar onlar oluşturulmaz. Ayrıca her seferinde örnek oluşturulur. GetCustomAttributes iki kez üst üste çağrıldığında, iki farklı ObsoleteAttribute örneği döndürür.

Çalışma zamanındaki ortak öznitelikler

Öznitelikler birçok araç ve çerçeve tarafından kullanılır. NUnit, NUnit test çalıştırıcısı tarafından kullanılan [Test] ve [TestFixture] gibi özellikler kullanır. ASP.NET MVC, gibi [Authorize] öznitelikleri kullanır ve MVC eylemleri üzerinde çapraz kesme endişeleri gerçekleştirmek için bir eylem filtresi çerçevesi sağlar. PostSharp , C# dilinde boyut odaklı programlamaya izin vermek için öznitelik söz dizimini kullanır.

.NET Core temel sınıf kitaplıklarında yerleşik olarak bulunan birkaç önemli öznitelik şunlardır:

  • [Obsolete]. Bu, yukarıdaki örneklerde kullanılmıştır ve ad alanında yer alır System . Değişen bir kod tabanı hakkında bildirim temelli belgeler sağlamak yararlıdır. Bir ileti bir dize biçiminde sağlanabilir ve derleyici uyarısından derleyici hatasına geçmek için başka bir boole parametresi kullanılabilir.
  • [Conditional]. Bu öznitelik ad alanındadır System.Diagnostics . Bu öznitelik yöntemlere (veya öznitelik sınıflarına) uygulanabilir. Oluşturucuya bir dize geçirmeniz gerekir. Bu dize bir #define yönergeyle eşleşmiyorsa, C# derleyicisi bu yönteme yapılan çağrıları kaldırır (ancak yöntemin kendisini kaldırmaz). Bu tekniği genellikle hata ayıklama (tanılama) amacıyla kullanırsınız.
  • [CallerMemberName]. Bu öznitelik parametrelerde kullanılabilir ve ad alanında System.Runtime.CompilerServices bulunur. CallerMemberName , başka bir yöntemi çağıran yöntemin adını eklemek için kullanılan bir özniteliktir. Bu, çeşitli ui çerçevelerinde INotifyPropertyChanged uygularken 'sihirli dizeleri' ortadan kaldırmanın bir yoludur. Örnek olarak:
public class MyUIClass : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler? PropertyChanged;

    public void RaisePropertyChanged([CallerMemberName] string propertyName = default!)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    private string? _name;
    public string? Name
    {
        get { return _name;}
        set
        {
            if (value != _name)
            {
                _name = value;
                RaisePropertyChanged();   // notice that "Name" is not needed here explicitly
            }
        }
    }
}

Yukarıdaki kodda sabit bir "Name" dizesine sahip olmanız gerekmez. Kullanmak CallerMemberName yazım hatasıyla ilgili hataları önler ve ayrıca daha sorunsuz yeniden düzenleme/yeniden adlandırma sağlar. Öznitelikler C# için bildirim temelli güç getirir, ancak bunlar bir meta veri kod biçimidir ve tek başına hareket etmemektedir.