Yanıtlar:
Evet, ama readonly
yerine beyan etmelisiniz const
:
public static readonly string[] Titles = { "German", "Spanish", "Corrects", "Wrongs" };
Bunun nedeni const
sadece değeri derleme zamanında bilinen bir alana uygulanabilmesidir. Gösterdiğiniz dizi başlatıcısı C # 'da sabit bir ifade değildir, bu yüzden bir derleyici hatası üretir.
O bildirilmesi readonly
(tertibin kullanılması ilk önce başlatılır olduğu garanti olsa da) bir değer kadar çalıştırma başlatıldı değildir, çünkü bu sorunu çözer.
Sonuçta ne elde etmek istediğinize bağlı olarak, bir numaralandırma bildirmeyi de düşünebilirsiniz:
public enum Titles { German, Spanish, Corrects, Wrongs };
readonly static
istenen semantik herhangi bir benzerlik var.
static
Çalışması için bana gerekli değil, sadece Titles
örnek olmadan başvuru yapma imkanı ekler , ancak farklı örnekler için değeri değiştirme olasılığını kaldırır (örneğin, o readonly
alanın değerini değiştirdiğinize bağlı olarak parametreyle yapıcıya sahip olabilirsiniz ).
Diziyi şu şekilde bildirebilirsiniz readonly
, ancak readonly
dizi öğesini değiştirebileceğinizi unutmayın .
public readonly string[] Titles = { "German", "Spanish", "Corrects", "Wrongs" };
...
Titles[0] = "bla";
Cody'nin önerdiği gibi enum veya IList kullanmayı düşün.
public readonly IList<string> ITitles = new List<string> {"German", "Spanish", "Corrects", "Wrongs" }.AsReadOnly();
const
DEĞİL hakkında readonly
...
Bir 'const' dizisi oluşturamazsınız çünkü diziler nesnedir ve yalnızca çalışma zamanında oluşturulabilir ve const varlıkları derleme zamanında çözülür.
Bunun yerine dizinizi "salt okunur" olarak bildirmektir. Bu, const ile aynı etkiye sahiptir, ancak değer çalışma zamanında ayarlanabilir. Sadece bir kez ayarlanabilir ve daha sonra salt okunur (yani sabit) bir değerdir.
const int[] a = null;
çok yararlı olmayan, ama aslında bir dizi sabitinin bir örneğidir.
C # 6'dan beri şöyle yazabilirsiniz:
public static string[] Titles => new string[] { "German", "Spanish", "Corrects", "Wrongs" };
Ayrıca bkz: C #: Yeni ve Geliştirilmiş C # 6.0 (özellikle "İfade Gövdeli İşlevler ve Özellikler" bölümü)
Bu salt okunur bir statik özellik oluşturur, ancak yine de döndürülen dizinin içeriğini değiştirmenize izin verir, ancak özelliği yeniden çağırdığınızda, orijinal, değiştirilmemiş diziyi tekrar alırsınız.
Açıklığa kavuşturmak için, bu kod (veya aslında kısayol) ile aynıdır:
public static string[] Titles
{
get { return new string[] { "German", "Spanish", "Corrects", "Wrongs" }; }
}
Lütfen bu yaklaşımın bir dezavantajı olduğunu unutmayın: Her referansta yeni bir dizi başlatılır, bu nedenle çok büyük bir dizi kullanıyorsanız, bu en etkili çözüm olmayabilir. Ancak aynı diziyi yeniden kullanırsanız (örneğin özel bir özniteliğe koyarak) dizinin içeriğini değiştirme olasılığını tekrar açacaktır.
Değişmez bir diziye (veya listeye) sahip olmak istiyorsanız şunları da kullanabilirsiniz:
public static IReadOnlyList<string> Titles { get; } = new string[] { "German", "Spanish", "Corrects", "Wrongs" };
Ancak, yine de bir dizgiye [] geri döndürebileceğiniz ve içeriği değiştirebileceğiniz için, bunun yine de değişiklik riski vardır:
((string[]) Titles)[1] = "French";
Titles[0]
Örneğin, aslında atama girişimi sessizce göz ardı edilirse bir derleme hatası almazsınız . Diziyi her seferinde yeniden yaratmanın verimsizliğiyle birlikte, bu yaklaşımın gösterilmeye değer olup olmadığını merak ediyorum. Aksine, 2. yaklaşım etkilidir ve değişmezliği yenmek için kendi yolunuzdan çıkmanız gerekir.
IReadOnlyList arabiriminin arkasında bir dizi bildirirseniz, çalışma zamanında bildirilen sabit değerlere sahip sabit bir dizi alırsınız:
public readonly IReadOnlyList<string> Titles = new [] {"German", "Spanish", "Corrects", "Wrongs" };
.NET 4.5 ve sonraki sürümlerinde kullanılabilir.
TDBeckett'in cevabını geliştiren bir .NET Framework v4.5 + çözümü :
using System.Collections.ObjectModel;
// ...
public ReadOnlyCollection<string> Titles { get; } = new ReadOnlyCollection<string>(
new string[] { "German", "Spanish", "Corrects", "Wrongs" }
);
Not: Koleksiyonun kavramsal olarak sabit olduğu düşünüldüğünde, onu sınıf düzeyinde static
beyan etmek mantıklı olabilir .
Yukarıdaki:
Özelliğin örtülü yedekleme alanını bir kez diziyle başlatır .
Not o { get; }
- yani sadece bir özellik ilan getter - örtük salt okunur özelliğini kendisi kılan (birleştirmeye çalışıyor readonly
ile { get; }
aslında bir yazım hatasıdır).
Alternatif olarak, sorudaki gibi bir özellik yerine bir alan oluşturmak için atlayabilir { get; }
ve ekleyebilirsiniz , ancak genel veri üyelerini alanlar yerine özellikler olarak göstermeniz iyi bir alışkanlıktır.readonly
Her ikisi de şunlarla ilgili olarak gerçekten ve sağlam bir şekilde salt okunur (kavramsal olarak sabit, oluşturulduktan sonra sabit ) olan dizi benzeri bir yapı oluşturur ( dizinli erişime izin verir ) :
IReadOnlyList<T>
solüsyon, bir (string[])
döküm elemanları yazma erişimi kazanmak için kullanılabilir gösterildiği gibi, mjepsen en yararlı cevap . IReadOnlyCollection<T>
ReadOnlyCollection
IReadOnlyCollection
dizine eklenen erişimi desteklemediğinden burada kullanılamaz. Ek olarak, IReadOnlyList
(endeksli erişimi olan) gibi, geri dönerek eleman manipülasyonuna açıktır string[]
. Başka bir deyişle: ReadOnlyCollection
(bir dize dizisini yayınlayamayacağınız) en sağlam çözümdür. Bir alıcı kullanmamak bir seçenektir (ve bunu not etmek için cevabı güncelledim), ancak genel verilerle bir mülke bağlı kalmak daha iyidir.
Benim ihtiyaçları static
için imkansız yerine dizi tanımlamak const
ve çalışır:
public static string[] Titles = { "German", "Spanish", "Corrects", "Wrongs" };
const
OP örneğinden kaldırmanız da işe yarar, ancak bu (veya cevabınız) hem Titles
örneği hem de herhangi bir değeri değiştirmeye izin verir . Peki bu cevabın anlamı nedir?
readonly
const
/ readonly
dikkate almadan, nasıl çalıştıracağınız ( const
sözdizimi hatasıymış gibi) doğrudan. Bazı insanlar için değerli bir cevap gibi görünüyor (belki de const
yanlışlıkla kullanmaya çalıştılar mı?).
Farklı bir yaklaşım kullanabilirsiniz: dizinizi temsil etmek için sabit bir dize tanımlayın ve ardından dizeyi ihtiyacınız olduğunda bir diziye bölün;
const string DefaultDistances = "5,10,15,20,25,30,40,50";
public static readonly string[] distances = DefaultDistances.Split(',');
Bu yaklaşım size konfigürasyonda saklanabilen ve gerektiğinde bir diziye dönüştürülebilen bir sabit verir.
Tamlık uğruna, şimdi de elimizde ImmutableArrays var. Bu gerçekten değişmez olmalı:
public readonly static ImmutableArray<string> Tiles = ImmutableArray.Create(new[] { "German", "Spanish", "Corrects", "Wrongs" });
System.Collections.Immutable NuGet başvurusu gerektirir
https://msdn.microsoft.com/en-us/library/mt452182(v=vs.111).aspx
Bu, istediğinizi yapmanın bir yoludur:
using System;
using System.Collections.ObjectModel;
using System.Collections.Generic;
public ReadOnlyCollection<string> Titles { get { return new List<string> { "German", "Spanish", "Corrects", "Wrongs" }.AsReadOnly();}}
Salt okunur bir dizi yapmaya çok benzer.
public static readonly ReadOnlyCollection<String> Titles = new List<String> { "German", "Spanish", "Corrects", "Wrongs" }.AsReadOnly();
; Zaten bir ReadOnlyCollection yaparsanız, her almada listeyi yeniden oluşturmanız gerekmez.
Tek doğru cevap bu. Şu anda bunu yapamazsınız.
Diğer tüm cevaplar, bir sabite benzeyen fakat aynı olmayan statik salt okunur değişkenlerin kullanılmasını önermektedir . Bir sabit, düzeneğe sert kodlanmıştır. Statik salt okunur bir değişken bir kez ayarlanabilir, muhtemelen bir nesne başlatıldığında.
Bunlar bazen değiştirilebilir, ancak her zaman değil.
Alternatif olarak, salt okunur bir diziyle değiştirilebilen öğelerle ilgili sorunu gidermek için bunun yerine statik bir özellik kullanabilirsiniz. (Tek tek öğeler yine de değiştirilebilir, ancak bu değişiklikler yalnızca dizinin yerel kopyasında yapılacaktır.)
public static string[] Titles
{
get
{
return new string[] { "German", "Spanish", "Corrects", "Wrongs"};
}
}
Tabii ki, her seferinde yeni bir dize dizisi oluşturulduğundan bu özellikle etkili olmayacaktır.
En iyi alternatif:
public static readonly byte[] ZeroHash = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };