Bu konuda bir iş arkadaşınızla dostane bir tartışma yapmak. Bununla ilgili bazı düşüncelerimiz var, ancak SO kalabalığının bu konuda ne düşündüğünü merak ediyoruz.
Bu konuda bir iş arkadaşınızla dostane bir tartışma yapmak. Bununla ilgili bazı düşüncelerimiz var, ancak SO kalabalığının bu konuda ne düşündüğünü merak ediyoruz.
Yanıtlar:
Bunun bir nedeni, salt okunur yerel için CLR desteğinin olmamasıdır. Salt okunur, CLR / CLI initonly işlem koduna çevrilir. Bu bayrak yalnızca alanlara uygulanabilir ve yerel için bir anlamı yoktur. Aslında, bunu yerel bir yere uygulamak muhtemelen doğrulanamayan kod üretecektir.
Bu, C # 'ın bunu yapamayacağı anlamına gelmez. Ama aynı dil yapısına iki farklı anlam verecektir. Yerellere yönelik sürümde CLR eşdeğeri eşleme olmayacaktır.
readonly
Etkisi nedeniyle alanlar için anahtar kelime CLI tarafından desteklenmesi gerekiyor ise diğer meclislere görünür. Bunun anlamı, derleme zamanında değişkenin yöntemde yalnızca bir ataması olmasıdır.
const
(C ++' da C # ' readonly
dan çok C # gibidir const
, ancak her iki rolü de oynayabilir). Yine de C ++ const
yerel otomatik değişkeni destekler . Bu nedenle, readonly
yerel değişken için bir C # için CLR desteğinin olmaması önemsizdir.
using
ve out
tam olarak yapıyor bu vardır ve dünya çökmedi.
Bence bu, C # mimarlarının bir kısmı için zayıf bir karar. Yerel değişkenler üzerindeki salt okunur değiştirici, programın doğruluğunu korumaya yardımcı olur (tıpkı iddialar gibi) ve derleyicinin kodu optimize etmesine yardımcı olabilir (en azından diğer dillerde). Şu anda C # 'da izin verilmediği gerçeği, C #' ın bazı "özelliklerinin" yalnızca yaratıcılarının kişisel kodlama stilinin bir zorlaması olduğunun başka bir argümanıdır.
Jared'in cevabına değinecek olursak, muhtemelen sadece bir derleme zamanı özelliği olması gerekecekti - derleyici, ilk bildirimden sonra (bir atama içermesi gereken) değişkene yazmanızı yasaklayacaktır.
Bunun değerini görebilir miyim? Potansiyel olarak - ama çok değil, dürüst olmak gerekirse. Yöntemin başka bir yerinde bir değişkenin atanıp atanmayacağını kolayca anlayamıyorsanız, yönteminiz çok uzundur.
Ne 's değerinde için Java (kullanarak bu özelliği vardır final
değiştirici) ve ben ettik çok nadiren o durumlar dışında kullanılan görüldü sahip değişken Anonim iç sınıf tarafından yakalanan izin vermek için kullanılacak - nerede ve olduğu kullanıldığında, bana faydalı bilgilerden çok dağınıklık izlenimi veriyor.
readonly
/ final
değerleri val
ve var
anahtar sözcükleriyle değişkenlerden ayırır . Scala kodunda, yerel val
s çok sık kullanılır (ve aslında yerel kodlara göre tercih edilir var
). final
Java'da değiştiricinin daha sık kullanılmamasının başlıca nedenlerinin a) dağınıklık ve b) tembellik olduğundan şüpheleniyorum .
readonly
için aşırı önemli olmayacaktır. Öte yandan, kapanışlarda kullanılan yerel değişkenler için readonly
, çoğu durumda derleyicinin daha verimli kod üretmesine izin verir. Şu anda, yürütme bir kapatma içeren bir bloğa girdiğinde , kapatmayı kullanacak hiçbir kod çalıştırılmasa bile , derleyici kapalı değişkenler için yeni bir yığın nesnesi yaratmalıdır . Bir değişken salt okunursa, kapanışın dışındaki kod normal bir değişken kullanabilir; yalnızca kapanış için bir temsilci oluşturulduğunda ...
C # 7 tasarım ekibi tarafından salt okunur yereller ve parametreler için bir teklif kısaca tartışıldı. Gönderen Jan 21, 2015 yılı için C # Tasarım Toplantı Notları :
Parametreler ve yereller lambdalar tarafından yakalanabilir ve bu nedenle eşzamanlı olarak erişilebilir, ancak bunları paylaşılan karşılıklı durum sorunlarından korumanın bir yolu yoktur: salt okunur olamazlar.
Genel olarak, çoğu parametre ve birçok yerel öğenin, başlangıç değerlerini aldıktan sonra hiçbir zaman atanması amaçlanmamıştır. Onlara salt okunur izin vermek, bu niyeti açıkça ifade edecektir.
Bir sorun, bu özelliğin "çekici bir sıkıntı" olabileceğidir. Yapılacak "doğru şey" neredeyse her zaman parametreleri ve yerelleri salt okunur hale getirmek olsa da, bunu yapmak kodu önemli ölçüde karıştırır.
Bunu kısmen hafifletmek için bir fikir, yerel bir değişkendeki salt okunur varyasyon kombinasyonunun val veya bunun gibi kısa bir şeye bağlanmasına izin vermektir. Daha genel olarak, salt okunurluğu ifade etmek için oluşturulmuş salt okunurdan daha kısa bir anahtar kelime düşünmeye çalışabiliriz.
Tartışma C # Dil Tasarımı deposunda devam ediyor. Desteğinizi göstermek için oy verin. https://github.com/dotnet/csharplang/issues/188
C # dil tasarımcısı için bir gözetimdir. F #, val anahtar kelimesine sahiptir ve CLR'ye dayanır. C # 'ın aynı dil özelliğine sahip olmaması için hiçbir sebep yoktur.
Ben o iş arkadaşıydım ve arkadaşça değildi! (şaka yapıyorum)
Bu özelliği ortadan kaldırmam çünkü kısa yöntemler yazmak daha iyidir. Bu biraz zor oldukları için iplik kullanmamalısın demek gibi. Bıçağı bana ver ve kendimi kesmememin sorumluluğunu bana ver.
Kişisel olarak, dağınıklığı önlemek için "inv" (değişmez) veya "rvar" gibi başka bir "var" türü anahtar kelime istedim. Son zamanlarda F # üzerinde çalışıyorum ve değişmez şeyi çekici buluyorum.
Java'nın buna sahip olduğunu hiç bilmiyordum.
Yerel sabit değişkenleri sevdiğim gibi, yerel salt okunur değişkenleri de istiyorum . Ancak diğer konulardan daha az önceliğe sahiptir.
Belki de önceliği , C # tasarımcılarının bu özelliği (henüz!) Uygulamamaları için aynı nedendir . Ancak gelecekteki sürümlerde yerel salt okunur değişkenleri desteklemek kolay (ve geriye dönük uyumlu) olmalıdır.
Salt okunur, örnek değişkeninin ayarlanabileceği tek yerin yapıcıda olduğu anlamına gelir. Bir değişkeni yerel olarak bildirirken, bir örneği yoktur (sadece kapsam dahilindedir) ve kurucu tarafından dokunulamaz.
Biliyorum, bu sorunun nedenini yanıtlamıyor. Her neyse, bu soruyu okuyanlar yine de aşağıdaki kodu takdir edebilirler.
Yalnızca bir kez ayarlanması gereken yerel bir değişkeni geçersiz kılarken kendinizi ayağa kaldırmakla gerçekten ilgileniyorsanız ve onu daha genel olarak erişilebilir bir değişken yapmak istemiyorsanız, bunun gibi bir şey yapabilirsiniz.
public class ReadOnly<T>
{
public T Value { get; private set; }
public ReadOnly(T pValue)
{
Value = pValue;
}
public static bool operator ==(ReadOnly<T> pReadOnlyT, T pT)
{
if (object.ReferenceEquals(pReadOnlyT, null))
{
return object.ReferenceEquals(pT, null);
}
return (pReadOnlyT.Value.Equals(pT));
}
public static bool operator !=(ReadOnly<T> pReadOnlyT, T pT)
{
return !(pReadOnlyT == pT);
}
}
Örnek kullanım:
var rInt = new ReadOnly<int>(5);
if (rInt == 5)
{
//Int is 5 indeed
}
var copyValueOfInt = rInt.Value;
//rInt.Value = 6; //Doesn't compile, setter is private
Belki daha az kod rvar rInt = 5
olmasa da işe yarıyor.
C # etkileşimli derleyiciyi kullanıyorsanız, C # 'da salt okunur yerel değişkenler bildirebilirsiniz csi
:
>"C:\Program Files (x86)\MSBuild\14.0\Bin\csi.exe"
Microsoft (R) Visual C# Interactive Compiler version 1.3.1.60616
Copyright (C) Microsoft Corporation. All rights reserved.
Type "#help" for more information.
> readonly var message = "hello";
> message = "goodbye";
(1,1): error CS0191: A readonly field cannot be assigned to (except in a constructor or a variable initializer)
Ayrıca .csx
komut dosyası biçiminde salt okunur yerel değişkenler de bildirebilirsiniz .
message
burada bir değişken değil, bir alana derlenmiştir. Bu nitpicking değildir çünkü ayrım etkileşimli C #'da da açıkça mevcuttur: int x; Console.WriteLine(x)
yasal etkileşimli C # (çünkü x
bir alandır ve dolaylı olarak başlatılmıştır), ancak void foo() { int x; Console.WriteLine(x); }
değildir (çünkü x
bir değişkendir ve atanmadan önce kullanılır). Ayrıca, Expression<Func<int>> y = x; ((MemberExpression) y.Body).Member.MemberType
bunun x
gerçekten bir alan olduğunu ve yerel bir değişken olmadığını ortaya çıkaracaktır .
c #, biraz farklı bir sözdiziminde de olsa, zaten salt okunur bir değişkene sahiptir:
Aşağıdaki satırları düşünün:
var mutable = myImmutableCalculationMethod();
readonly var immutable = mutable; // not allowed in C# 8 and prior versions
return immutable;
İle karşılaştırmak:
var mutable = myImmutableCalculationMethod();
string immutable() => mutable; // allowed in C# 7
return immutable();
Kuşkusuz, ilk çözüm muhtemelen yazılacak daha az kod olabilir. Ancak 2. kod parçası, değişkene atıfta bulunurken salt okunuru açık hale getirecektir.
readonly var im = new List<string>(); im.Add("read-only variable, mutable object!");
.
const
salt okunur değişken yapmak için anahtar sözcük kullanın.
referans: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/const
public class SealedTest
{
static void Main()
{
const int c = 707;
Console.WriteLine("My local constant = {0}", c);
}
}
const
Değişkenin yalnızca başlatma sırasında atanabileceği JavaScript tarzı ile ilgileniyoruz - const
yalnızca derleme zamanı ifadelerinin kullanılabildiği csharp tarzı değil . Örneğin, yapamazsınız const object c = new object();
ancak readonly
yerel bir kişi bunu yapmanıza izin verir.