Salt Okunur Örnek Üyeleri
Not
Bu makale bir özellik belirtimidir. Belirtim, özelliğin tasarım belgesi olarak görev alır. Önerilen belirtim değişikliklerini ve özelliğin tasarımı ve geliştirilmesi sırasında gereken bilgileri içerir. Bu makaleler, önerilen belirtim değişiklikleri son haline getirilene ve geçerli ECMA belirtimine dahil edilene kadar yayımlanır.
Özellik belirtimi ile tamamlanan uygulama arasında bazı tutarsızlıklar olabilir. İlgili dil tasarım toplantısı (LDM) notlarında, bu farklılıklar kaydedilir.
Özellik belirtimlerini C# dil standardına benimseme işlemi hakkında daha fazla bilgi edinmek için
Gündemdeki Sorun: https://github.com/dotnet/csharplang/issues/1710
Özet
Yapının tek tek örnek üyelerinin durumu değiştirmediğini belirtmenin bir yolunu sağlayın; tıpkı readonly struct
'ın hiçbir örnek üyenin durumu değiştirmediğini belirttiği gibi.
salt okunur örnek üyesinin != saf örnek üyesiolduğuna dikkat çekmek gerekir.
saf örnek üyesi hiçbir durumun değiştirilmeyeceğini garanti eder.
readonly
örnek üyesi yalnızca örnek durumunun değiştirilmeyeceğini garanti eder.
Motivasyon
C# 8.0'ın öncesinde kullanıcılar, derleyicinin tüm alanların salt okunur olmasını zorunlu kıldığı (ve uzantıya göre hiçbir örnek üyesinin durumu değiştirmediği) readonly struct
türleri oluşturabilir. Ancak, erişilebilir alanları açığa çıkaran veya değiştirilebilir ve değiştirilemez üyelerin karışımına sahip mevcut bir API'niz olduğu bazı senaryolar vardır. Bu koşullar altında, türü readonly
olarak işaretleyemezsiniz (hataya neden olan bir değişiklik olacaktır).
Bunun normalde in
parametreleri dışında çok fazla etkisi olmaz. Salt okunur olmayan yapılar için in
parametreleri ile, derleyici, çağrının iç durumu değiştirmediğini garanti edemediği için her örnek üyesi çağrısı için parametrenin bir kopyasını oluşturur. Bu, çok sayıda kopyaya ve yapıyı doğrudan değere göre geçirmiş olmanızdan daha kötü bir genel performansa yol açabilir. Örneğin, keskin bu koda bakın
Gizli kopyaların oluşabileceği diğer senaryolar arasında static readonly
alanları ve değişmez değerleribulunmaktadır. Gelecekte destekleniyorsa, kesilebilir sabitler aynı teknede sonuçlanacaktır; yapısı readonly
olarak işaretlenmemişse, hepsi şu anda tam bir kopya (örnek üye çağrısı) gerektirir.
Tasarım
Kullanıcının bir örnek üyesinin kendisi readonly
olduğunu ve örneğin durumunu değiştirmediğini belirtmesine izin verin (derleyici tarafından yapılan tüm uygun doğrulamalar ile elbette). Mesela:
public struct Vector2
{
public float x;
public float y;
public readonly float GetLengthReadonly()
{
return MathF.Sqrt(LengthSquared);
}
public float GetLength()
{
return MathF.Sqrt(LengthSquared);
}
public readonly float GetLengthIllegal()
{
var tmp = MathF.Sqrt(LengthSquared);
x = tmp; // Compiler error, cannot write x
y = tmp; // Compiler error, cannot write y
return tmp;
}
public readonly float LengthSquared
{
get
{
return (x * x) +
(y * y);
}
}
}
public static class MyClass
{
public static float ExistingBehavior(in Vector2 vector)
{
// This code causes a hidden copy, the compiler effectively emits:
// var tmpVector = vector;
// return tmpVector.GetLength();
//
// This is done because the compiler doesn't know that `GetLength()`
// won't mutate `vector`.
return vector.GetLength();
}
public static float ReadonlyBehavior(in Vector2 vector)
{
// This code is emitted exactly as listed. There are no hidden
// copies as the `readonly` modifier indicates that the method
// won't mutate `vector`.
return vector.GetLengthReadonly();
}
}
Özellik erişimcilerine salt okunur, erişimcide this
'ın değiştirilmediğini belirtmek için uygulanabilir. Bu erişimciler üye alanının durumunu değiştirdiğinden ancak bu üye alanının değerini değiştirmediğinden, aşağıdaki örneklerde salt okunur ayarlayıcılar vardır.
public readonly int Prop1
{
get
{
return this._store["Prop1"];
}
set
{
this._store["Prop1"] = value;
}
}
Özellik söz dizimine readonly
uygulandığında, bu, tüm erişimcilerin readonly
olduğu anlamına gelir.
public readonly int Prop2
{
get
{
return this._store["Prop2"];
}
set
{
this._store["Prop2"] = value;
}
}
Salt okunur, yalnızca içeren türü değiştirmeyen erişimcilere uygulanabilir.
public int Prop3
{
readonly get
{
return this._prop3;
}
set
{
this._prop3 = value;
}
}
Otomatik özelliklerin bazılarına salt okunur olarak uygulanabilir, ancak bunun anlamlı bir etkisi olmaz. Derleyici, otomatik gerçekleştirilen tüm get işlevlerini readonly
anahtar sözcüğü bulunsa da bulunmasa da salt okunur olarak değerlendirir.
// Allowed
public readonly int Prop4 { get; }
public int Prop5 { readonly get; set; }
// Not allowed
public int Prop6 { readonly get; }
public readonly int Prop7 { get; set; }
public int Prop8 { get; readonly set; }
Salt okunur, el ile uygulanan olaylara uygulanabilir, ancak alan benzeri olaylara uygulanamaz. Tek tek olay işleyicisi erişimcilerine salt okunur olarak uygulanamaz (ekleme/kaldırma).
// Allowed
public readonly event Action<EventArgs> Event1
{
add { }
remove { }
}
// Not allowed
public readonly event Action<EventArgs> Event2;
public event Action<EventArgs> Event3
{
readonly add { }
readonly remove { }
}
public static readonly event Event4
{
add { }
remove { }
}
Diğer bazı söz dizimi örnekleri:
- İfade gövdeli üyeler:
public readonly float ExpressionBodiedMember => (x * x) + (y * y);
- Genel kısıtlamalar:
public readonly void GenericMethod<T>(T value) where T : struct { }
Derleyici her zamanki gibi örnek üyesini yayar ve ayrıca örnek üyesinin durumu değiştirmediğini belirten derleyici tarafından tanınan bir öznitelik de yayar. Bu, gizli this
parametresinin ref T
yerine in T
olmasına neden olur.
Bu, kullanıcının derleyicinin bir kopya oluşturmasına gerek kalmadan söz konusu örnek yöntemini güvenli bir şekilde çağırmasına olanak tanır.
Kısıtlamalar şunlardır:
-
readonly
değiştirici statik yöntemlere, oluşturuculara veya yıkıcılara uygulanamaz. -
readonly
değiştirici temsilcilere uygulanamaz. -
readonly
değiştiricisi sınıf veya arabirimin üyelerine uygulanamaz.
Dezavantaj -ları
Bugün readonly struct
yöntemlerinde olduğu gibi aynı dezavantajlar. Bazı kodlar yine de gizli kopyalara neden olabilir.
Notlar
Bir özniteliği veya başka bir anahtar sözcüğü kullanmak da mümkün olabilir.
Bu teklif, her ikisi de mevcut tekliflere sahip olan functional purity
ve/veya constant expressions
ile ilgilidir (ancak daha çok bir alt kümesidir).
C# feature specifications