2009-10-16 7 views
7

Bu konuyla ilgili bazı tartışmalar okudum ve anlamadığım bir şey var.Mülkiyet vs İşlev (özellikle .NET)

En yaygın yanıt şu şekildedir: önbelleğe alınmış verileri döndürmek için bir ReadOnly Property kullanın, önbelleğe alınmamış verileri döndürmek için bir İşlev kullanın. WriteOnly Mülkiyeti hiç kullanmayın, çünkü "mantıklı değil".

Bunun için bir neden yok. IL'de, MyProperty, get_MyProperty ve set_MyProperty yöntemleri olarak bulunur. Bunun tek nedeni, yukarıdaki cevabın varsayılması gerektiğidir.

Tamam, o zaman neden ReadOnly Properties ile hiç uğraşmıyorsunuz? Neden sadece Private değil Özel değişken yapmak değil? Öyleyse neden Properties ile uğraşmak istersiniz? Önbelleğe alınmış veriler -> Genel değişken, önbelleğe alınmamış veriler -> Altyazı, veri yazma -> Alt

Yukarıdakilerin hepsini unutalım ve Özellikleri kullanışlı bir özellik olarak kullanalım mı? Verileri Al ve Ayarla bir 'öğe'. Get'in önbelleğe alınmış verileri döndürmeyeceğini (muhtemelen gecikmeye neden olacak) bilmek için sağduyu kullanın.

-Edit- Kişilerin en iyi seçenek olduğunu daha fazla veya daha az kabul ettiklerini görüyorum. İnsanların neden mülklere karşı savunuculuğunu yaptığı birçok tartışmayı neden anladım.

+1

Sorunun tam olarak nedir? Son paragrafınız ya sorunuzla çelişir ya da kendi cevabınızı verir. –

+0

Son paragraf kendi fikrimi sağlıyor. Anlaşma veya anlaşmazlık arıyorum (sağlanan nedenlerle). – Stijn

+4

http://stackoverflow.com/questions/1019571/why-do-we-use-net-properties-instead-of-plain-old-get-set-functions – Jimmy

cevap

13

Salt okunur özellikler için iyi bir neden, hesaplanan değerlerdir. Bu durumda ihraç edilecek bir değişken yoktur. Bir özellik olarak _birthday maruz veya bir saha kesinlikle tartışmalıdır verilip Bu durumda

public class Person { 
    private readonly DateTime _birthday; 
    public int Age { get { return (DateTime.Now - _birthday).TotalYears; } } 
    ... 
} 

Örneğin

için

. Fakat Age gibi diğer hesaplanmış değerler için, onları bir değişken olarak ortaya çıkarmanın tek yolu onları nesnede saklamaktır. Bu durumda, Age için fazladan bir değişkene sahip olmak, esas olarak gereksiz bilgileri saklamaktır. Hesaplanan özellik olarak açığa vurmak, azami ek yüke sahiptir ve gereksiz verileri saklamaktan kaçınır.

3

Oto özelliklerden daha fazla özellik var. Bunu yaparsanız:

public int MyProp { 
    get { 
     // Do some processing 
     return someValue; 
    } 

    set { 
     // Do some processing 
     DoMyProcess(value); 
    } 
} 

Diğeri kodu:

public int MyProp { public get; public set; } 

Sonra

public int MyProp; 

Ancak eski büyük avantajı, daha sonra bunu değiştirebilirsiniz olduğunu gerçekten farklı değil Nesnenizi kullanan, yeniden derleme olmadan çalışır. Bunun yerine, bir genel alan kullanmış olsaydınız, bir alandan bir mülke değiştirmek istediğinizde istemci kodunun yeniden derlenmesi gerekecektir.

+0

Özelliklerin bu "yararı" fazlasıyla vurgulanmıştır. , Benim fikrimce. Tabii ki, çok sayıda "ikili tüketici" ile kütüphaneler, çerçeveler, vb yazanlar için çok önemlidir. Ama üzerinde çalıştığım .NET projelerinin çoğu için, "dünyayı yeniden inşa etmek" kolaydı. –

+0

@Dan: Haklısın, çalıştığım projelerin% 90'ı için de önemli değil. Diğer her şey gibi, özellikler bir araçtır - eğer yardımcı olurlarsa kullanmazlarsa, onları yok sayın. Ancak, bu kadar çok neden vurgulanmış olmasının nedeni, insanların neden Java'da getters ve setterlar yazdığının aynı nedenden, hatta "eğer (foo == 0)' yerine "eğer (0 == foo)' yazıyorsa) Bir alışkanlık haline gelen bir savunma kodlama mekanizması. Pek çoğu, alışkanlığın çabaya değer olduğunu tartışırdı. Yine, eğer yardımcı olursa, onu kullanın. –

+0

C# 3'ün otomatik uygulamalı özellikleriyle, buradaki girişte yüzmeyi denemiyorum. Yine de, benim kullanımlarımın çoğu için, bir alan gayet iyi çalışırdı - ve eğer açık bir get/sete ihtiyacım olursa, bir mülke geçmek, her şeyi yeniden inşa edeceğime göre büyük bir anlaşma olmayacaktır. Evet, bir alandan bir mülke geçerken kırılacak parametreler gibi bir kaç köşe durumu vardır. –

3

Özellikler, yöntem tabanlı işlemler için uygun bir alternatiftir. Bir özellik-alıcı-belirleyici ile aynı eylemleri gerçekleştiren bir yöntem arasında işlevsel bir fark yoktur; Aslında, IL'ye bakarsanız, mülk erişimlerinin "get" ve/veya "set" yöntemleriyle değiştirildiğini görürsünüz.

Özelliklerin yalnızca değişkenlere erişmesine izin vermek için kullanılmasının en güçlü nedeni kapsülleme. Bir kütüphane yazdığını ve bir IsBlue değişkenini ortaya çıkardığını varsayalım. Kütüphaneyi dağıtıyorsunuz, herkes onu seviyor ve kullanıyor.Şimdi, sürüm 2 zamanı ve kullanıcı IsBlue ayarlandığında bir şeyler yapmak istersiniz - belki bir kontrol yapın, belki bir şeyi önbelleğe alın. Bunu yapmak için, değişkeni bir mülke veya yönteme dönüştürmeniz ve check in işlemini orada yapmanız gerekir. Artık tüm müşteri kodunuzu kırdınız - eriştikleri değişken artık yok. Başlangıçta bir mülk olarak uyguladıysanız, mülkün kodunu değiştirmiş olabilirsiniz ve ikili uyumluluğu koruyabilirdiniz.

1

"Önbelleğe alınmış veri -> Genel değişken" - kötü bir fikir. Bu, başka bir sınıfın önbelleğe alınmış verileri değiştirmesine izin verir. Ayrıca, önbellekleme için verileri hesaplamak pahalı olabilir: salt okunur özelliği kullanmak, mülke erişilene kadar hesaplamayı ertelemenize olanak tanır.

0

Değişkeninizi sınıfınızdan açığa çıkarmak kötü bir uygulama olarak kabul edilir. Ayrıca, nesnenizin yapısını değiştirir, ancak özelliklerinizi sağlam tutarsanız, sınıfınızı kullanan kodu etkilemez.

5

Sebep # 1 = Veri bağlamada özellikler kullanılabilir. Yöntemler olamaz.

Sebep # 2 = İzleme penceresindeki hata ayıklama işlemi otomatik olarak özellikleri gösterecek/nesneyi genişletecektir. Yöntemler otomatik olarak bu şekilde izlenmez.

Okuma özelliğinin nesne durumunu değiştirmemesi gereken bir yer okumayı hatırlıyorum. Özellikle 2 numaralı sebebi gözetmek için iyi bir uygulama olduğunu düşünüyorum. Bir nesneyi izlediğinizde ve onu saatte genişlettiğinizde, nesneler durumu değiştirilebilir ve böylece hata ayıklama daha da zorlaşır. Ayrıca, pahalı bir özellik kaza ile bağlıysa, ciddi performans sorunları da ortaya çıkarabilir. (Öznitelikler, veri bağlayıcısından özellikleri gizleyebilir, ancak yalnızca bunları yapma yöntemleri, endişelenmenize gerek olmadığı anlamına gelir.)

Özellikler, pencere geliştirme için kolaylıklardır. Onlar vb tasarımcıları farklı "kullanılan" olan

(bazen sadece bazı değişkenleri açığa Ama onlara isim olarak isterim bir özellik Yani yerine

Tamsayı mCounter = 0;..

Sadece do

Tamsayı Sayaç = ;.

ben de aynı isimde Mülkiyet oluşturmak gelecekte bir noktada "ekstra şeyler" yapmak ve mCounter değişkeni yeniden adlandırın. Kuşkusuz bu tembellik üzerindedir varsa 0 benim bölümüm ve ben gerçekten yeniden değil Onu tadın. Sadece bir mülkte sarın.)