Farklı alıcı stilleri arasındaki C # farkı


154

Bazen alıcı için özelliklerde kısaltmalar görüyorum. Örneğin bu iki tür:

public int Number { get; } = 0

public int Number => 0;

Birisi bana bu ikisi arasında herhangi bir fark olup olmadığını söyleyebilir mi? Nasıl davranıyorlar? İkisi de salt okunur mu?

Yanıtlar:


266

Evet, ikisi de salt okunur, ancak bir fark var. İlkinde, yapıcı yürütülmeden önce 0 olarak başlatılan bir destek alanı vardır. Değeri , normal bir salt okunur alan gibi yalnızca yapıcıda değiştirebilirsiniz . Alıcının kendisi yalnızca alanın değerini döndürür.

İkincisinde, alıcı her seferinde 0 döndürür ve herhangi bir alan içermez.

Dolayısıyla, otomatik olarak uygulanan özellikleri veya ifade gövdeli üyeleri kullanmaktan kaçınmak için:

İlk versiyon

private readonly int _number = 0;
public int Number { get { return _number; } }

İkinci versiyon

public int Number { get { return 0; } }

Farkın daha net bir örneği şöyle görülebilir:

public DateTime CreationTime { get; } = DateTime.UtcNow;
public DateTime CurrentTime => DateTime.UtcNow;

Tek bir nesne oluşturursanız, CreationTimeözelliği her zaman aynı sonucu verir - çünkü nesne yapısında başlatılan salt okunur bir alanda depolanır. Ancak, CurrentTimemülke her eriştiğinizde bu DateTime.UtcNowdeğerlendirilmeye neden olur , böylece potansiyel olarak farklı bir sonuç elde edersiniz.


23
İkinci sürümün her zaman aynı değeri döndürmediğini unutmayın. İyi bir örnek, geri dönerseniz random.NextInt(). İlk sürüm bunu bir kez değerlendirecek ve her zaman aynı değere sahip olacaktır. İkincisi her seferinde yeni bir değer döndürür.

248

Farklardan biri bunun ne zaman 0değerlendirildiğidir: nesne oluştururken veya özellik kullanıldığında.

DateTime özellikleri ile bunu daha iyi görebilirsiniz:

class SomeTestClass
{
    public DateTime Start { get; } = DateTime.Now;

    public DateTime Now => DateTime.Now;
}

StartMülkiyet ederken, (örnek ne zaman oluşturulduğuna) aynı zamanda dönen tutar Nowdeğişiklikler geçerli zamanı yansıtacak şekilde.

Açıklama :

İlk sürüm ("Başlat"), kurucu tarafından üzerine yazılabilecek bir başlangıç ​​değeri sağlar. Yani bu sadece bir kez değerlendirilir.
İkinci sürüm ("Now"), bu özelliğin "alıcısı" olacak ifadeyi sağlar. Bu özellik, özellik her okunduğunda değerlendirilir. Oluşturucunun üzerine yazabileceği bir destek alanı bile yoktur.


26
Bu bence en önemli ayrım.
Matthew

14
Kabul edilen cevap, örnek koddaki farkı en kesin olarak tanımlar, ancak bu, iki yapıdaki daha faydalı bir farkı açıklar.
Kamil Drakari

3
Wow, ünlü Jon Skeet'in kendisinden daha fazla oy aldın.
machine_1

21

Bunlar C # 6 dil özellikleridir.

İlk örnek

public int Number { get; } = 0

İlk örnek, yalnızca alıcıya özgü bir otomatik özelliktir . Yalnızca alıcı otomatik özelliğinin destek alanı örtülü olarak salt okunur olarak bildirilir.

İkinci örnek

public int Number => 0;

İkinci örnek, özellik benzeri işlev üyeleri üzerindeki ifade gövdeleridir . Herhangi bir getanahtar kelime olmadığını unutmayın : İfade gövdesi sözdiziminin kullanılmasıyla ima edilir.

Her ikisi de salt okunur.


5
... ama Jon Skeet'in açıkladığı gibi, birincisinin döndürdüğü değeri değiştirebilirsiniz.
Martin Bonner

2
@MartinBonner ... ama sadece kurucuda.
Dennis Kuypers

5
veya her zaman olduğu gibi, yansıma yoluyla (küçük nitpicking)
Marco Mp
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.