Özel alanları olan veya olmayan özellikleri tercih etmeli miyim?


16

Şu anda çalıştığım kod temeli, özel alanları ve genel özellikleri kullanma kuralına sahiptir. Örneğin, çoğu sınıfın üyeleri şu şekilde tanımlanır:

// Fields
private double _foo;
private double _bar;
private double _baz;

// Properties
public double Foo
{
    get{ return _foo; }
    set{ _foo = value; }
}

public double Bar
{
    get{ return _bar; }
    set{ _bar = value; }
}

public double Baz
{
    get{ return _baz; }
}

Bunların dahili özel özellikleri olmadan yeniden yazılabileceğini biliyorum :

public double Foo{ get; set; }
public double Bar{ get; set; }
public double Baz{ get; private set; }

Bu konuda bazı girdiler istiyorum:

  • Daha yeni, daha özlü olana göre eski, daha açık stili tercih etmek için iyi bir neden var mı?
  • Kısa stili kullanarak yeni sınıflar yazmalı mıyım yoksa tutarlılık için eski kodu eşleştirmeye çalışmalı mıyım? Bu durumda tutarlılık eski formatı haklı çıkarmak için yeterli midir?


@PeterK. Bilgilendirici. Programın geri kalanının stiline uyma konusunda endişelenmem gerekip gerekmediği veya önemli olmamak için yeterince küçük bir ayrıntı olup olmadığı konusunda cevap vermez.
KChaloux

@KChaloux: Anlaşıldı! Bu yüzden bu bir yorum, cevap değil. :-)
Peter K.

@PeterK. Fuar 'nuff = p
KChaloux

1
değişmemek için başka bir neden WCF ile tel üzerinden bir şey geçirilirse - otomatik özellikler sözleşme sorunları (.NET tarafından oluşturulan destek alanı adlarındaki geçersiz karakterler nedeniyle)
Leon

Yanıtlar:


16

"Eski" stilin hala gerekli olduğu birkaç örnek vardır:

C: Dille sağlanan değişmezliği kullanan değişmez türler. readonlyC # değiştirici yapımından sonra bu değeri donar. Bunu otomatik olarak uygulanan özelliklerle (henüz) taklit etmenin bir yolu yoktur.

public sealed class FooBarBazInator
{
    private readonly double foo;

    public FooBarBazInator(double foo)
    {
        this.foo = foo;
    }

    public double Foo
    {
        get
        {
            return this.foo;
        }
    }
}

B: Alıcılarınız / ayarlayıcılarınız herhangi bir mantığa sahiptir. Sınıflarınıza veri bağlı olan WPF ve Silverlight (ve benzeri) kodları aşağıdaki INotifyPropertyChangedgibi uygulanacaktır :

public class FooBarBazInator : INotifyPropertyChanged
{
    private double foo;

    public event PropertyChangedEventHandler PropertyChanged;

    public double Foo
    {
        get
        {
            return this.foo;
        }

        set
        {
            this.foo = value;
            this.RaisePropertyChanged("Foo");
        }
    }

    private void RaisePropertyChanged(string propertyName)
    {
        var propertyChanged = this.PropertyChanged;

        if (propertyChanged != null)
        {
            propertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

Bunların dışında yeni stili kullan diyebilirim. Kodunuzu kısa ve öz tutar ve hataların içine girmesi için daha az yüzey alanı sunar.


2
Herkes yeni stille gitme konusunda hemfikir görünüyor. readonlyBildiğim değiştiriciyle bir alanın gerekliliğini anlattığım için +1 ve yanıt kredisi alıyorsunuz . = D
KChaloux

3
Bazıları (ben dahil), özel erişimli oto mülkleri değişmez mülkler için “yeterince iyi” olarak görmektedir. Doğru, gerçekten değişmez olmayabilirler, ancak ayarlayıcıyı yapıcı dışında kullanmamaya dikkat etmelisiniz.
svick

2
başka bir neden, değeri refözelliklerle çalışmadığı gibi iletmek istiyorsanız , bu yüzden alana ihtiyacınız var
stijn

1
Fody gibi bir araç INotifyPropertyChanged, açık destek alanlarına ihtiyaç duymadan uygulama yapabilir. github.com/Fody/PropertyChanged
Sebastian Redl

3
Unutmayın: C # 6, "A" örneğimin ne yaptığını tek satırda sağlayan "yalnızca alıcı otomatik özellikleri" ne izin verir.
Jesse C. Slicer

6

Açık bir destek alanına sahip olmanın işe yaramaz bir şey olduğunu söyleyebilirim: kodunuzu daha uzun ve okumak daha zor hale getirir. Ayrıca hata potansiyeli ekler:

public double Bar
{
    get { return _baz; }
    set { _bar = value; }
}

Bunun gibi bir hata oldukça kolay olabilir ve fark edilmesi oldukça zor olur.

Tutarlılık istiyorsanız, bunu başka bir şekilde yapın: yedekleme alanlarını kullanan kodu, otomatik özellikleri kullanan koda dönüştürün. ReSharper gibi bir yeniden düzenleme aracı kullanıyorsanız (ve böyle bir şey kullanmıyorsanız, başlamanız gerektiğini düşünüyorum) bu özellikle kolaydır.

Tabii ki, hala destek alanına sahip olmanın gerekli olduğu durumlar var, ancak bunun bu soru ile ilgili olmadığını düşünüyorum.


Aslında kodu yeniden düzenlerken birkaç eski alanda bunu yaptım ... bu bir acı.
KChaloux

1

Soru oldukça eski olmasına rağmen burada bahsetmeye değer bir kitaptan okuduğum birkaç nokta eklemeyi düşündüm.

  1. Çalışma zamanı serileştirme motorları serileştirilmiş bir akışta dosyalanmış olanın adını korur. Otomatik olarak uygulanan bir özelliğin (AIP) destek alanının adı derleyici tarafından belirlenir ve kodunuzu her yeniden derlediğinizde bu destek alanının adını değiştirebilir ve bu, AIP. Bu nedenle, serileştirmek veya serisini kaldırmak istediğiniz herhangi bir türle AIP kullanmayın.

  2. Hata ayıklama sırasında, bir AIP alma veya ayarlama yöntemine kesme noktası koyamazsınız; bu nedenle, bir uygulamanın bu özelliği ne zaman aldığını veya ayarladığını kolayca algılayamazsınız. Manuel olarak uygulanan kesme noktalarında kesme noktaları ayarlayabilirsiniz


3
# 1 - Çoğu serileştirici varsayılan olarak özel özellikleri / alanları yok sayar; Bahsettiğiniz sorunlarla hiç karşılaşmadım. # 2 - Bu VS2015'te sabittir ve VS2013'te çözülebilir. Bkz bu Visual Studio Dergisi makalesine .
Brian

-3

Daha yeni, daha özlü olana göre eski, daha açık stili tercih etmek için iyi bir neden var mı?

Pek sayılmaz. Her ne kadar böyle bir mülkten geçtiğinizde, başlamak için sadece bir kamusal alan kullanmanız gerektiğini iddia etmeliyim.

Kısa stili kullanarak yeni sınıflar yazmalı mıyım yoksa tutarlılık için eski kodu eşleştirmeye çalışmalı mıyım? Bu durumda tutarlılık eski formatı haklı çıkarmak için yeterli midir?

Yukarıdaki tavsiyeleri göz ardı ettiğiniz ve geçme özelliklerine sahip olduğunuzu varsayarsak, stili eşleştirmeyi amaçlamam. İdeal olarak, geriye dönüp eski stili yeni stile uygun hale getirmek için tekrar düzenlersiniz, ancak insanların bu kodu yanlış anlama şansı zayıftır.



@svick - Bah. Eğer tipte yansıma yapmadığınız sürece hiçbir fark yoktur. Türü genel olarak bir hizmet veya kitaplık arabirimi olarak açığa çıkarıyorsanız, yine de bir özellik gerektirecek bir arabirimi ortaya koyacaksınız. OP bu şeylerin hiçbirini yapmıyor.
Telastyn

2
Bu sınırlı durumlarda teknik bir neden yoktur . Unutmayın özellikleri hata ayıklayıcı, sınıf diyagramları, intellisense farklı davranır ve sadece yansıma yapmadığınızı düşünüyorsanız, .NET framework. WinForms, WPF ve diğer bazı bileşenler dahili olarak yansıma kullanır ve özellikleri ayrı ayrı ele alırlar, bu nedenle genel alanları kullanma önerisi bu sitedeki birçok geliştirici tarafından zayıf bir şekilde alınacaktır.
Kevin McCormick

1
@KevinMcCormick ve çerçeve (anladığım kadarıyla) alanlarla mükemmel bir şekilde davranır. Şu anda oto-mülkler olduğu için gerçekten önemli değil , ancak daha büyük sorun şeyleri halka duyurmak. Çok fazla insan, bir şeyleri basitçe mülk haline getirmenin onları bir şekilde 'kamusal alan yapma' dan kurtardığını düşünüyor.
Telastyn

2
Çerçeve bunları farklı şekilde ele alır: EF POCO'da ortak bir alan kullanmayı deneyin, bir DataGridView'a bağlayın, bir PropertyGrid kullanın, vb. yüzlerce kez, ama GetField için değil. Sonuç olarak, farklıdırlar ve herkese açık veriler için her zaman özellikleri kullanma önerisi kısmen bu gerçeğe dayanmaktadır. Bu, alanların kullanılmasını engellemez, ancak bu durumun gerekçelendirilmesi gerekir. Bununla birlikte, diğer noktanız kesinlikle doğrudur, halka açık verileri dikkatsizce ortaya çıkarmak her zaman kötü bir fikirdir.
Kevin McCormick
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.