Arasındaki fark nedir const
ve readonly
C #?
Birini ne zaman diğerinin üzerinde kullanırsınız?
Arasındaki fark nedir const
ve readonly
C #?
Birini ne zaman diğerinin üzerinde kullanırsınız?
Yanıtlar:
Görünen fark dışında
const
VS readonly
değerleri için bir tanım sırasındaki değeri beyan etmek dinamik olarak hesaplanabilir, ancak yapıcıdan çıkmadan önce atanmaları gerekir.static
. ClassName.ConstantName
Bunlara erişmek için bir gösterim kullanırsınız.İnce bir fark var. 'De tanımlanan bir sınıfı düşünün AssemblyA
.
public class Const_V_Readonly
{
public const int I_CONST_VALUE = 2;
public readonly int I_RO_VALUE;
public Const_V_Readonly()
{
I_RO_VALUE = 3;
}
}
AssemblyB
referans verir AssemblyA
ve bu değerleri kodda kullanır. Bu derlendiğinde,
const
değer durumunda, bul-değiştir gibi, 2 değeri IL'nin 'içine' pişirilir ' AssemblyB
. Bu, yarın I_CONST_VALUE
gelecekte 20'ye güncelleyeceğim anlamına gelir . AssemblyB
yeniden derleyene kadar hala 2 olurdu .readonly
değer olması durumunda, ref
bir bellek konumuna a gibidir. Değer, AssemblyB
IL'ye dönüştürülmez . Bu, bellek konumu güncellenirse, AssemblyB
yeni değeri yeniden derlemeden alır demektir. Yani I_RO_VALUE
30 olarak güncellenirse, sadece inşa etmeniz gerekir AssemblyA
. Tüm istemcilerin yeniden derlenmesi gerekmez.Yani sabitin değerinin değişmeyeceğinden eminseniz a kullanın const
.
public const int CM_IN_A_METER = 100;
Ancak değişebilecek bir sabitiniz varsa (örn. Hassas) .. veya şüpheniz varsa, a kullanın readonly
.
public readonly float PI = 3.14;
Güncelleme: Aku, önce dikkat çektiğinden bahsetmek gerekiyor. Ayrıca ben bu yerde öğrendim takmak gerekir .. Etkili C # - Bill Wagner
static
Nokta en önemli ve yararlı nokta olarak görülmektedir -consts are implicitly static
readonly
değişkenler yapıcı (yansıma) dışında değiştirilebilir. Sadece kurucu dışında var değiştirmek için engel olmaya çalışır derleyici.
readonly
değişkenlerinin kurucu bittikten sonra, yansıma yoluyla bile değiştirilmesine izin verilmez. Çalışma zamanı bunu zorlamıyor. Çalışma zamanı da değişmez zorunlu kılmak amacıyla değil olur string.Empty
üzere "Hello, world!"
, ama yine de bu hale getirdiğini iddia olmaz string.Empty
değiştirilemez veya bu kod farz edilmemelidir string.Empty
her zaman sıfır uzunluklu dize olacaktır.
Consts ile bir gotcha var! Başka bir derlemeden bir sabite başvurursanız, değeri doğrudan çağrı derlemesine derlenir. Bu şekilde başvurulan derlemedeki sabiti güncellediğinizde, çağrı derlemesinde değişmez!
Sadece eklemek için, ReadOnly referans türleri için sadece referansları değil değerleri salt okunur yapar. Örneğin:
public class Const_V_Readonly
{
public const int I_CONST_VALUE = 2;
public readonly char[] I_RO_VALUE = new Char[]{'a', 'b', 'c'};
public UpdateReadonly()
{
I_RO_VALUE[0] = 'V'; //perfectly legal and will update the value
I_RO_VALUE = new char[]{'V'}; //will cause compiler error
}
}
string
Sabit olarak kullanabileceğiniz başka bir referans türü var mı ?
const
Dize dışındaki referans türlerine sahip olabilirsiniz , ancak sabit yalnızca değere sahip olabilir null
.
Bu açıklıyor . Özet: const bildirim zamanında başlatılmalı, salt yapıcı üzerinde başlatılabilir (ve dolayısıyla kullanılan yapıcıya bağlı olarak farklı bir değere sahip olabilir).
EDIT: ince fark için yukarıdaki Gishu gotcha bakın
Küçük bir gotcha ile salt okunur. Bir salt okunur alan, yapıcı (lar) içinde birden çok kez ayarlanabilir. Değer, iki farklı zincir oluşturucuda ayarlanmış olsa bile, buna izin verilir.
public class Sample {
private readonly string ro;
public Sample() {
ro = "set";
}
public Sample(string value) : this() {
ro = value; // this works even though it was set in the no-arg ctor
}
}
Derleme zamanında sabit bir üye tanımlanır ve çalışma zamanında değiştirilemez. Sabitler const
anahtar kelime kullanılarak bir alan olarak bildirilir ve bildirildikçe başlatılmaları gerekir.
public class MyClass
{
public const double PI1 = 3.14159;
}
Bir readonly
üye değişmeyen bir değeri temsil ettiği için sabit gibidir. Fark, bir readonly
üyenin çalışma zamanında, bir kurucuda başlatılabilmesinin yanı sıra bildirildikçe başlatılabilmesidir.
public class MyClass1
{
public readonly double PI2 = 3.14159;
//or
public readonly double PI3;
public MyClass2()
{
PI3 = 3.14159;
}
}
const
static
(dolaylı olarak statiktirler)Sadece oku
static const int i = 0;
const
Beyanların neden yöntemlerle yapılamadığını açıklayabilir misiniz ?
Const bir derleme zamanı sabitidir, oysa salt değer bir değerin çalışma zamanında hesaplanmasına ve yapıcı veya alan başlatıcıda ayarlanmasına izin verir. Dolayısıyla, bir 'sabit' her zaman sabittir, ancak 'salt okunur' atandığında salt okunurdur.
C # ekibinden Eric Lippert'in farklı değişmezlik türleri hakkında daha fazla bilgi var
Const'un sürüm güvenliğini veya referans türleri için ne kadar alakalı olmadığını gösteren başka bir bağlantı .
Özet :
Salt Okunur : Değer çalışma zamanında Ctor aracılığıyla değiştirilebilir. Ancak üye İşlev aracılığıyla değil
Sabit : Statik statik ile. Değer herhangi bir yerden değiştirilemez (Ctor, İşlev, çalışma zamanı vb.
Yine başka bir gotcha: salt okunur değerler yansıma yoluyla "sapkın" kod ile değiştirilebilir.
var fi = this.GetType()
.BaseType
.GetField("_someField",
BindingFlags.Instance | BindingFlags.NonPublic);
fi.SetValue(this, 1);
Yansıtma kullanarak C # özel bir salt miras alan değiştirebilir miyim?
Bir const
değerin tüm nesneler için aynı olduğuna (ve gerçek ifadeyle başlatılması gerektiğine) inanıyorum, oysa readonly
her örnekleme için farklı olabilir ...
Ofisimizdeki ekip üyelerinden biri, const, static ve readonly'nin ne zaman kullanılacağı konusunda aşağıdaki rehberliği sağlamıştır:
Son bir not: sabit alan statiktir, ancak tersi doğru değildir.
Her ikisi de sabittir, ancak derleme zamanında da bir sabit mevcuttur. Bu, farkın bir yönünün, const değişkenlerini öznitelik yapıcılarına girdi olarak kullanabileceğiniz, ancak salt okunur değişkenleri kullanabileceğiniz anlamına gelir.
Misal:
public static class Text {
public const string ConstDescription = "This can be used.";
public readonly static string ReadonlyDescription = "Cannot be used.";
}
public class Foo
{
[Description(Text.ConstDescription)]
public int BarThatBuilds {
{ get; set; }
}
[Description(Text.ReadOnlyDescription)]
public int BarThatDoesNotBuild {
{ get; set; }
}
}
ne zaman kullanılır const
veyareadonly
const
readonly
App.config
, ancak başlatıldıktan sonra değiştirilemezConst olarak işaretlenen değişkenler, güçlü bir şekilde yazılan #define makrolarından biraz daha fazladır, derleme zamanında const değişken referansları satır içi değişmez değerlerle değiştirilir. Sonuç olarak bu şekilde sadece belirli yerleşik ilkel değer türleri kullanılabilir. Salt okunur olarak işaretlenen değişkenler, bir kurucuda çalışma zamanında ayarlanabilir ve salt okunur olmaları çalışma zamanı sırasında da uygulanır. Bununla ilişkili bazı küçük performans maliyetleri vardır, ancak herhangi bir türle (hatta referans türleri) salt okunur olarak kullanabileceğiniz anlamına gelir.
Ayrıca, const değişkenleri doğal olarak statikken, salt okunur değişkenler istenirse örneğe özgü olabilir.
Başka bir yakaladım .
Const gerçekten sadece temel veri türleriyle çalıştığından, bir sınıfla çalışmak istiyorsanız ReadOnly'ı kullanmak için "zorlanmış" hissedebilirsiniz. Ancak, tuzağa dikkat! ReadOnly, nesneyi başka bir nesneyle değiştiremeyeceğiniz anlamına gelir (başka bir nesneye başvurmasını sağlayamazsınız). Ancak nesneye referansı olan herhangi bir işlem, nesnenin içindeki değerleri değiştirmekte özgürdür !
Bu nedenle, ReadOnly'nin bir kullanıcının bazı şeyleri değiştiremeyeceğini ima ettiğini düşünmeyin. Bir sınıf örneğinin dahili değerlerinin değişmesini (bildiğim kadarıyla) değiştirmesini önlemek için C # 'da basit bir sözdizimi yoktur.
C # .Net'te const ve salt okunur alanlar arasında dikkate değer bir fark vardır.
const varsayılan olarak statiktir ve daha sonra değiştirilemeyen sabit değerle başlatılması gerekir. Yapıcılarda da değer değişikliğine izin verilmez. Tüm veri tipleriyle kullanılamaz. Ex DateTime için. DateTime veri tipiyle kullanılamaz.
public const DateTime dt = DateTime.Today; //throws compilation error
public const string Name = string.Empty; //throws compilation error
public readonly string Name = string.Empty; //No error, legal
salt okunur olarak statik olarak bildirilebilir, ancak gerekli değildir. Beyan sırasında başlatmaya gerek yoktur. Değeri kurucu kullanılarak atanabilir veya değiştirilebilir. Bu nedenle, örnek sınıf üyesi olarak kullanıldığında avantaj sağlar. İki farklı örneklemenin salt okunur alanın değeri farklı olabilir. Eski için -
class A
{
public readonly int Id;
public A(int i)
{
Id = i;
}
}
Daha sonra salt okunur alan aşağıdaki gibi anlık spesifik değerlerle başlatılabilir:
A objOne = new A(5);
A objTwo = new A(10);
Burada, objOne örneği 5 olarak salt okunur alan değerine sahip olacak ve objTwo'nun 10 değeri vardır. Bu, const kullanılarak mümkün değildir.
Bir sabit, değişmez değer olarak tüketiciye derlenirken, statik dize tanımlanan değere bir başvuru işlevi görür.
Bir alıştırma olarak, harici bir kütüphane oluşturmayı deneyin ve bir konsol uygulamasında tüketin, ardından kütüphanedeki değerleri değiştirin ve yeniden derleyin (tüketici programını yeniden derlemeden), DLL'i dizine bırakın ve EXE'yi manuel olarak çalıştırın, bulmalısınız. sabit dize değişmez.
Sabit
Değer tanımlandığında const alanına değer sağlamalıyız. Derleyici daha sonra sabitin değerini derlemenin meta verilerine kaydeder. Bu, bir sabitin yalnızca boolean, char, byte vb. Gibi ilkel tipler için tanımlanabileceği anlamına gelir. Sabitler örnek üyeler değil, her zaman statik üyeler olarak kabul edilir.
Sadece oku
Salt okunur alanlar yalnızca çalışma zamanında çözülebilir. Bu, alanın bildirildiği tür için yapıcıyı kullanarak bir değer için bir değer tanımlayabileceğimiz anlamına gelir. Doğrulama, derleyici tarafından salt okunur alanların kurucu dışında herhangi bir yöntemle yazılmadığı şeklinde yapılır.
Her ikisi de bu makalede açıklanan hakkında daha fazla bilgi
Const ve salt okunur benzerdir, ancak tam olarak aynı değildirler. Bir const alanı derleme zamanı sabitidir, yani bu değer derleme zamanında hesaplanabilir. Salt okunur bir alan, türün oluşturulması sırasında bazı kodların çalıştırılması gereken ek senaryolar sağlar. İnşaattan sonra, salt okunur bir alan değiştirilemez.
Örneğin, const üyeleri aşağıdaki gibi üyeleri tanımlamak için kullanılabilir:
struct Test
{
public const double Pi = 3.14;
public const int Zero = 0;
}
3.14 ve 0 gibi değerler derleme zamanı sabitleridir. Ancak, bir tür tanımladığınız ve bu türün bazı fab öncesi örneklerini sağlamak istediğiniz durumu göz önünde bulundurun. Örneğin, bir Color sınıfı tanımlamak ve Siyah, Beyaz vb. Ortak renkler için "sabitler" sağlamak isteyebilirsiniz. Sağ taraflar derleme zamanı sabitleri olmadığından bunu const üyeleriyle yapmak mümkün değildir. Bunu düzenli statik üyelerle yapabiliriz:
public class Color
{
public static Color Black = new Color(0, 0, 0);
public static Color White = new Color(255, 255, 255);
public static Color Red = new Color(255, 0, 0);
public static Color Green = new Color(0, 255, 0);
public static Color Blue = new Color(0, 0, 255);
private byte red, green, blue;
public Color(byte r, byte g, byte b) {
red = r;
green = g;
blue = b;
}
}
ancak o zaman Renk müşterisinin belki de Siyah Beyaz değerlerini değiştirerek onunla uğraşmasını engelleyecek hiçbir şey yoktur. Söylemeye gerek yok, bu, Color sınıfının diğer istemcileri için şaşkınlığa neden olur. "Salt okunur" özellik bu senaryoyu ele alır. Yalnızca bildirimlere salt okunur anahtar sözcüğü ekleyerek, esnek kod başlatmayı korurken istemci kodunun karışmasını önleriz.
public class Color
{
public static readonly Color Black = new Color(0, 0, 0);
public static readonly Color White = new Color(255, 255, 255);
public static readonly Color Red = new Color(255, 0, 0);
public static readonly Color Green = new Color(0, 255, 0);
public static readonly Color Blue = new Color(0, 0, 255);
private byte red, green, blue;
public Color(byte r, byte g, byte b) {
red = r;
green = g;
blue = b;
}
}
Const üyelerinin her zaman statik olduğunu, ancak salt okunur bir üyenin normal bir alan gibi statik olabileceğini veya olmayabileceğini belirtmek ilginçtir.
Bu iki amaç için tek bir anahtar kelime kullanmak mümkündür, ancak bu sürüm oluşturma sorunlarına veya performans sorunlarına yol açar. Bir an için bunun için (const) tek bir anahtar kelime kullandığımızı ve bir geliştiricinin şunu yazdığını varsayın:
public class A
{
public static const C = 0;
}
ve farklı bir geliştirici A'ya dayanan bir kod yazdı:
public class B
{
static void Main() {
Console.WriteLine(A.C);
}
}
Şimdi, oluşturulan kod AC'nin derleme zamanı sabiti olmasına güvenebilir mi? Yani, AC kullanımı sadece 0 değeri ile değiştirilebilir mi? Buna "evet" derseniz, A geliştiricisinin AC'nin başlatılma şeklini değiştiremeyeceği anlamına gelir - bu, A geliştiricisinin ellerini izinsiz bağlar. Bu soruya "hayır" derseniz, önemli bir optimizasyon kaçırılır. Belki de A'nın yazarı AC'nin her zaman sıfır olacağı konusunda olumludur. Hem const hem de salt okunur kullanımı, A geliştiricisinin amacı belirtmesine izin verir. Bu, daha iyi sürüm oluşturma davranışı ve daha iyi performans sağlar.
Fark, statik bir salt okunur alanın değerinin çalışma zamanında ayarlanmasıdır, bu nedenle programın farklı yürütmeleri için farklı bir değere sahip olabilir. Ancak, bir const alanının değeri bir derleme zaman sabitine ayarlanır.
Unutmayın: Referans türlerinde, her iki durumda da (statik ve örnek) salt okunur değiştirici yalnızca alana yeni bir başvuru atamanızı önler. Özellikle referans ile gösterilen nesneyi değiştirilemez yapmaz.
Ayrıntılar için lütfen bu konuyla ilgili C # Sık Sorulan Sorular'a bakın: http://blogs.msdn.com/csharpfaq/archive/2004/12/03/274791.aspx
Sabit değişkenler derleme zamanında bildirilir ve başlatılır. Değer, servislerden sonra değiştirilemez. Salt okunur değişkenler yalnızca sınıfın Statik yapıcısından başlatılır. Salt okunur yalnızca değeri çalışma zamanında atamak istediğimizde kullanılır.
Sabit : Uygulama ömrü boyunca mutlak sabit değer.
Readonly : Çalışma süresinde değiştirilebilir.
İnsanların yukarıda söylediklerine eklemek için bir şey. Salt okunur bir değer içeren bir montajınız varsa (ör. Salt okunur MaxFooCount = 4;), bu montajın yeni bir sürümünü farklı bir değerle göndererek (örneğin salt okunur MaxFooCount = 5;) çağrı derlemelerinin gördüğü değeri değiştirebilirsiniz.
Ancak bir sabitle, arayan derlendiğinde arayanın koduna katlanır.
Bu C # yeterlilik seviyesine ulaştıysanız, bu soruyu ayrıntılı olarak yanıtlayan Bill Wagner'in Etkili C #: 50 Özel Yolları # ve diğer soruları cevaplamaya hazırsınız.