2008-10-03 32 views
160

böyle yazma sınıfları alışkınım: Bir otomatik özelliğine Bar dönüştürmebaşlatılıyor C# otomatik özellikleri

public class foo { 
    private string mBar = "bar"; 
    public string Bar { 
    get { return mBar; } 
    set { mBar = value; } 
    } 
    //... other methods, no constructor ... 
} 

kullanışlı ve özlü görünüyor, ama nasıl bir yapıcı ekleme ve koymadan başlatma koruyabilirsiniz orada başlatma var mı?

public class foo2theRevengeOfFoo { 
    //private string mBar = "bar"; 
    public string Bar { get; set; } 
    //... other methods, no constructor ... 
    //behavior has changed. 
} 

Bir yapıcı ekleyerek ben otomatik özelliklerinden elde etmem gerekiyordu çaba tasarrufu ile değil.END_DIV görebiliyordu. Böyle

Başıma bir şey daha mantıklı olur: Varsayılan yapıcı olarak

public string Bar { get; set; } = "bar"; 
+1

Yapımcıda yapmak istemediğiniz özel bir neden var mı? –

+13

Sadece daha önce bir kurucuda yapmak zorunda olmadığım için. Bu yüzden, bir kurucu eklemem gerekirse bana herhangi bir çaba harcamaz. – dlamblin

+5

STATIC özel dizesiyse ...? Sonra, yeni bir nesnenin oluşturulduğu her seferinde çağrılacak ve özellikle istemediği bir şey olarak kurucunun içinde init istemezsiniz. ~~~ –

cevap

173

Güncelleme - Aşağıdaki cevap C# 6 gelmeden önce yazılmıştır. C# 6'da yazabilirsiniz:

public class Foo 
{ 
    public string Bar { get; set; } = "bar"; 
} 

yapabilirsiniz da yazma yapıcı sadece yazılabilir olan otomatik uygulanan özelliklerini salt okunur (aynı zamanda varsayılan bir başlangıç ​​değeri verilebilir:

public class Foo 
{ 
    public string Bar { get; } 

    public Foo(string bar) 
    { 
     Bar = bar; 
    } 
} 

artık bu hakkı yapmanın bir yolu yoktur talihsiz bir durumdur. yapıcı değeri ayarlamak gerekir. (tekrardan kaçınmak için yardımcı olabilir yapıcı zincirleme kullanma.)

Otomatik olarak uygulanan özellikler şu anda kullanışlı, ancak kesinlikle daha hoş olabilir. Kendimi bu tür bir başlatmayı istediğim gibi, sadece yapıcıda ayarlanabilen ve salt okunur bir alanla desteklenen salt okunur otomatik olarak uygulanan bir özellik olarak görmüyorum.

Bu kadar ve C# 5 dahil olmak üzere olmadı, ancak C# 6 için planlanmaktadır - izin beyanı, noktasında başlatma izin veren şartlar ve hem salt okunur otomatik olarak uygulanır özellikleri başlatılması için bir kurucu vücutta.

+32

Bu VB.NET ekibinin doğru anladığı yerlerden biridir - VB'de mülkünüzü bildirebilir ve bu gibi aynı satırda ayarlayabilirsiniz: 'Kamu Mülkiyeti MyProp As String =" asdf "'. Ne yazık ki, C# gibi bir kamu alıcı ve özel bir belirteç ilan edemezsiniz. Ekiplerin bu özelliği neden doğru bir şekilde uygulayamadıklarından emin değilsiniz. – mattmc3

+4

@ mattmc3: Neredeyse haklı çıktılar. Bazı nedenlerle, başlangıçta okunan okuma-yazma özelliklerinden çok daha anlamlı olacak olsa bile, başlangıçta okunan otomatik özelliklerine izin vermezler. – supercat

+12

"Jon Skeet, C# 5.0 hakkında bir kitap yazmıştı. Şu anda mühürlenmiş durumda. Üç yıl içinde, Anders Hejlsberg, kitap tasarım ekibinin doğru olup olmadığını görmek için kitabı açacak." http://meta.stackexchange.com/a/9174 –

3

(ve herhangi bir varsayılan olmayan olanlar, herhangi bir çok tabii varsa):

public foo() { 
    Bar = "bar"; 
} 

budur Orijinal kodunuzun daha az performans gösterdiğine inanıyorum, çünkü bu zaten perde arkasında olan şey.

public class foo { 
    public foo(){ 
    Bar = "bar"; 
    } 
    public string Bar {get;set;} 
} 

başka yapıcısı var ise (yani paramters alır bir) ya da yapımcıların bir demet yapabilirsiniz daima var bu (denilen yapıcı:

+0

Sadece altta yatan alanını başlatmanın ve otomatik özelliği kullanılmaması ile kıyaslandığında, daha fazla iş var - Gerçekten bu senaryoda otomatik özelliğinden olsun kazanmak görmüyorum ... – Bittercoder

+2

bir yoktur fark, olsa da: Hemen başlatma, varsayılan kurucudan önce bile başlatıldığı anlamına gelir. Son zamanlarda anladığım garip bir nedenden dolayı bunun gerçekten önemli olduğu bir uygulama vardı. –

34

Sen sınıfının yapıcısı aracılığıyla yapabiliriz) zincirleme:

public class foo { 
    private foo(){ 
    Bar = "bar"; 
    Baz = "baz"; 
    } 
    public foo(int something) : this(){ 
    //do specialized initialization here 
    Baz = string.Format("{0}Baz", something); 
    } 
    public string Bar {get; set;} 
    public string Baz {get; set;} 
} 

her zaman orada ayarlanmış tüm varsayılan özellik başlatma olabilir varsayılan yapıcı bir çağrı zincirle edin. Zincirleme sırasında, zincirleme kurucu arama yapıcıdan önce çağrılır, böylece daha uzmanlaşmış kurucular sizin için geçerli olan farklı varsayılanları ayarlayabilir.

+1

Hmm Sanırım gerçekten 3 yol göstermedim ...: P –

+0

Son örnek, satır içi başlatmanın diğer yapıcı mantığından önce başlatılan değişkenlerde sonuçlanmasında biraz yanıltıcıdır. Kalıbınız, normal yapıcı mantığından sonra gerçekleşen başlatma işlemiyle sonuçlanır (en azından örnek 3, yapıcı için bir şey). Ben başlatılması onun noktası Şahsen genel inşaat sürecinde –

+0

, kendimi yani normalde diğer yolu kullanarak bulabilirsiniz. Genel olanı, özel olanı bazı varsayılan parametrelerle çağırır ve hiçbir şey yapmaz. Bu durumda, arama sırası gerçekten önemli değil. –

22

C# 6'da mümkün olacaktır.0:

public int Y { get; } = 2; 
İlgili konular