Yalnızca alıcılı otomatik mülk ayarlanabilir, neden?


97

Otomatik bir mülk oluşturdum:

public int Foo { get; } 

Bu yalnızca alıcıdır. Ancak bir kurucu oluşturduğumda değeri değiştirebilirim:

public MyClass(string name)
{
    Foo = 5;
}

Bu yalnızca elde edilebilir olmasına rağmen neden mümkün?


Aslında bir pasör kullanmaz (çünkü pasör yoktur). Doğrudan temel alanı belirler (bizden gizlidir, bu nedenle mülk adını kullanmanız gerekir)
Dennis_E

14
Asla başlatılamayan / ayarlanamayan bir özellik ne işe yarar ? Yacoub Massad buna mükemmel bir şekilde cevap verdi
Vikhram

Yanıtlar:


124

Bu yeni bir C # 6 özelliği olan "Getter-only auto-properties", aynı zamanda "Salt Okunur Özellikler için Otomatik Özellik Başlatıcıları" olarak da bilinir ve bu MSDN dergisi makalesi 'C #: The New and Improved C # 6.0' by Mark Michaelis ve C # 6.0 taslak Dil Belirtimi'nde .

Salt okunur alanın ayarlayıcısına yalnızca kurucuda erişilebilir, diğer tüm senaryolarda alan hala salt okunurdur ve eskisi gibi davranır.

Bu, yazmanız gereken kod miktarını azaltmak ve değeri tutmak için özel bir modül düzeyinde değişkeni açıkça bildirme ihtiyacını ortadan kaldırmak için kullanışlı bir sözdizimidir.

Bu özellik, C # 3'te Otomatik Uygulanan Özellikler'in kullanıma sunulmasından bu yana, değiştirilebilir özelliklerin (alıcı ve ayarlayıcıya sahip olanlar) değişmez olanlara (yalnızca alıcıya sahip olanlar) göre daha hızlı yazılmasından dolayı önemli görülmüştür. Genellikle salt okunur özellikler için gerekli olan bir arka alan için kod yazmak zorunda kalmamak için değiştirilebilir özellikler kullanma eğiliminde olmak. Microsoft C # Programlama Kılavuzu'nun ilgili bölümünde Otomatik Uygulanan özelliklerle ilgili daha fazla tartışma vardır .

Sean Sexton tarafından yazılan '# 1,207 - C # 6.0 - Salt Okunur Özellikler için Otomatik Mülk Başlatıcıları' başlıklı bu blog gönderisinde iyi bir açıklama ve örnek var:

C # 6.0'dan önce, salt okunur (değiştirilemez) bir özellik istiyorsanız, genellikle aşağıda gösterildiği gibi yapıcıda başlatılan salt okunur bir destek alanı kullanırdınız.

public class Dog 
{
    public string Name { get; set; }

    // DogCreationTime is immutable
    private readonly DateTime creTime;
    public DateTime DogCreationTime 
    {
        get { return creTime; }
    }

    public Dog(string name)
    {
        Name = name;
        creTime = DateTime.Now;
    }
}

C # 6.0'da, salt okunur bir özelliği uygulamak için otomatik uygulanan özellikleri kullanabilirsiniz. Bunu, bir otomatik özellik başlatıcı kullanarak yaparsınız. Sonuç, açıkça bir arka alan tanımlamamız gereken yukarıdaki örnekten çok daha temiz.

public class Dog
{
    public string Name { get; set; }

    // DogCreationTime is immutable
    public DateTime DogCreationTime { get; } = DateTime.Now;

    public Dog(string name)
    {
        Name = name;
    }
}

GitHub'daki dotnet Roslyn deposunda daha fazla ayrıntı da bulunabilir :

Otomatik özellikler artık bir ayarlayıcı olmadan bildirilebilir.

Yalnızca alıcıya açık bir otomatik mülkün destek alanı, örtük olarak salt okunur olarak bildirilir (bu yalnızca yansıtma amacıyla önemlidir). Yukarıdaki örnekte olduğu gibi özellik üzerinde bir başlatıcı aracılığıyla başlatılabilir. Ayrıca, bildirim türünün yapıcı gövdesinde yalnızca alıcı özelliği atanabilir, bu da değerin doğrudan temel alınan alana atanmasına neden olur:

Bu, türleri daha net bir şekilde ifade etmekle ilgilidir, ancak aynı zamanda değiştirilebilir ve değişmez türler arasındaki dildeki önemli bir farkı da ortadan kaldırdığına dikkat edin: otomatik özellikler, yalnızca sınıfınızı değiştirilebilir hale getirmeye istekli olmanız durumunda kullanılabilen bir kısaltmaydı ve dolayısıyla bu harikaydı. Şimdi, yalnızca alıcıya özgü otomatik özelliklerle, oyun alanı değiştirilebilir ve değiştirilemez arasında dengelendi.

ve C # 6.0 taslak Dil Spesifikasyonunda (NB: Microsoft söz konusu olduğunda dil spesifikasyonu nihaidir, ancak henüz bir EMCA / ISO standardı olarak onaylanmamıştır , dolayısıyla 'taslak'):

Otomatik olarak uygulanan özellikler

Otomatik olarak uygulanan bir özellik (veya kısaca otomatik özellik), yalnızca noktalı virgül erişimci gövdelerine sahip, soyut olmayan, harici olmayan bir özelliktir. Otomatik özelliklerin bir alma erişimcisi olması gerekir ve isteğe bağlı olarak ayarlanmış bir erişimci olabilir.

Bir özellik otomatik olarak uygulanan bir özellik olarak belirtildiğinde, özellik için otomatik olarak gizli bir destek alanı kullanılabilir ve erişimciler bu destek alanını okumak ve bu alana yazmak için uygulanır. Otomatik özelliğin ayarlı erişimcisi yoksa, destek alanı salt okunur olarak kabul edilir (Salt okunur alanlar). Tıpkı salt okunur bir alan gibi, bir salt alıcı otomatik özelliği, çevreleyen sınıfın bir yapıcısının gövdesine de atanabilir. Böyle bir atama, doğrudan mülkün salt okunur destek alanına atanır.

Bir otomatik özellik, isteğe bağlı olarak, bir değişken başlatıcı (Değişken başlatıcılar) olarak doğrudan destek alanına uygulanan bir özellik_ başlatıcıya sahip olabilir.


1
Bu aptalca bir tasarım. Özelliğin salt okunur olarak değerlendirildiği bir konumda ayarlanmışsa, bu bir derleme zamanı hatası olmalıdır.
Shiv

Benim için tuhaf olan, CS0200 C# Property or indexer cannot be assigned to -- it is read onlynormal bir özelliği kullanırken söyleyen hala bir derleyici hatası olması . "Yalnızca alıcıya özgü otomatik özellikler" salt okunur olarak kabul ediliyor mu, değil mi?
Kyle Delaney

24

Bu, C # 6'daki yeni bir özelliktir ve salt okunur özellikler oluşturmanıza ve değerlerini yapıcıdan (veya bunları bildirdiğinizde satır içi) başlatmanıza olanak tanır.

Bu özelliğin değerini kurucunun dışında değiştirmeye çalışırsanız, bu size bir derleme hatası verir.

Değerini başlattığınızda (satır içi veya yapıcının içinde) değerini değiştiremeyeceğiniz anlamında salt okunurdur.


Peki açıklaması ne? Getter'nin tanımı nedir?
Noam

16

Yapıcıdan (veya bir otomatik özellik başlatıcıdan) salt okunur özelliği başlatmak mümkün olmasaydı, o zaman her zaman türü için varsayılan değeri (sayısallar için 0, referans türleri için null) döndüreceğinden faydasız olurdu. ). Tüm C # sürümlerinde salt okunur alanlara uygulanan aynı anlambilim .

Gerçek bir salt alıcı özelliği (yapıcıdan başlatılamayan) tanımlamak için, tanımın bir parçası olarak ne döndürdüğünü belirtmeniz gerekir:

public int Foo { get { return 5; } }

Veya daha kısaca C # 6'da:

public int Foo => 5;

Tam olarak doğru değil, salt okunur özellikler kodunuzda bazı koşulları kapsüllemek için çok kullanışlıdır. Diğer özellikleri veya koşulları değerlendirmek için bir if ifadesi ve hemen hemen her kod yazabilir ve mülkü her okuduğunuzda uygun bir değer döndürebilirsiniz
sebagomez

3
@sebagomez: Anladığımdan emin değilim - örneğimde gösterdiğim şey bu değil mi?
Douglas

5

"Salt okunur otomatik olarak uygulanan özellikler"

Öncelikle mülkün beğendiğini açıklığa kavuşturmak istiyorum

public string FirstName { get; }

"Salt okunur otomatik olarak uygulanan özellikler" olarak bilinir

Bunu doğrulamak için, yukarıdaki kodu Visual Studio ile çalıştırabilir ve kontrol edebilirsiniz. Dil sürümünü C # 6.0'dan C # 5.0'a değiştirirseniz, derleyici aşağıdaki istisnayı atar Özelliği 'salt okunur otomatik olarak uygulanan özellikler' C # 5'te kullanılamaz. Lütfen dil sürümü 6 veya üzerini kullanın.

C # dil sürümünü değiştirmek için burayı ziyaret edin

Şimdi ikinci sorunuza geliyorum

"Bu sadece alıcı. Ancak bir kurucu oluşturduğumda değerini değiştirebilirim "

Microsoft, salt okunur mantığında "salt okunur otomatik olarak uygulanan özellikleri" sunar. "Salt okunur" anahtar kelimesinin C # 1.0'dan alınabildiğini bildiğimiz gibi. Biz “salt okunur” bir alanda değiştirici ve bu alan olarak anahtar kelime de atanabilir kullanın 2 şekilde ya ilanının anda veya aynı sınıfta yapıcı içinde.

Aynı şekilde, "salt okunur otomatik olarak uygulanan özellikler" değeri 2 şekilde atanabilir

Way1 (beyan anında):

public string FirstName { get; } = "Banketeshvar";

Way2 (aynı sınıftaki bir kurucuda)

Person()
{
 FirstName  = "Banketeshvar";
}

Salt ReadOnly Mülkiyet

Tamamen Salt Okunur mülk arıyorsanız, bunun için gidin

public string FullName => "Manish Sharma";

artık yapıcıdan "FullName" özelliğinin değerini atayamazsınız. Bunu yapmaya çalışırsanız, aşağıdaki istisnaları atacaktır

"Mülk veya dizin oluşturucu 'Person.FullName' atanamaz - salt okunurdur"


2
FullName => "foo bar" HER ZAMAN değerlendirilecektir.
juFo

4

Otomatik özellik özelliği, C # 3.0 sürümü sırasında dile eklendi. Herhangi bir destek alanı olmadan bir özelliği tanımlamanıza izin verir, ancak yine de bu otomatik özellikleri varsayılan olmayan bir değere başlatmak için yapıcıyı kullanmanız gerekir. C # 6.0, aşağıdaki gibi bir kurucu olmadan bu özellikleri başlatmanıza izin veren otomatik özellik başlatıcı adlı yeni bir özellik sunar:

Önceden, bir otomatik özellik kullanarak nesneler oluşturmak ve bir otomatik özelliği aşağıdaki gibi varsayılan olmayan bir değere başlatmak istiyorsanız bir yapıcı gereklidir:

public class MyClass
{
    public int Foo { get; }

    public Foo(int foo)
    {
        Foo = foo;
    }
}

Şimdi C # 6.0'da, auto-özellikli bir başlatıcı kullanma yeteneği, açık bir kurucu koduna gerek olmadığı anlamına gelir.

public string Foo { get; } = "SomeString";

public List<string> Genres { get; } = new List<string> { "Comedy", "Drama" };

Bununla ilgili daha fazla bilgiyi burada bulabilirsiniz


1

Bildirilen bir değişken readonlybir kurucu içinde yazılabilir, ancak özniteliği kullanan dillerde kurucu döndükten sonra değiştirilemez. Bu niteleyici bir dil özelliği olarak sağlandı çünkü genellikle değerleri yapıcı parametrelerine bağlı olarak değişen alanlar için gerekli (yani, kurucu başlamadan önce başlatılamazlar), ancak kurucular döndükten sonra değişmesi gerekmeyecek, ancak yalnızca alan olarak gösterilen değişkenler için kullanılabilir. readonlyNitelikli alanların anlambilgisi, çoğu durumda genel üyeler için mükemmel olurdu, ancak sınıfların üyeleri - değişmez olanları bile - alanlar yerine özellikler olarak göstermesi genellikle daha iyidir.

Sınıfların değişken özellikleri sıradan alanlar kadar kolay bir şekilde ortaya çıkarmasına izin vermek için okuma-yazma otomatik özelliklerinin var olması gibi, sınıfların değişmez özellikleri readonlynitelendirilmiş alanlar kadar kolay bir şekilde ortaya çıkarmasına izin veren salt okunur otomatik özellikler de vardır . Tıpkı readonlyulaşım kolaylığı alanlar olsun sadece özelliklere sahip bu yüzden de bir yapıcı yazılabilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.