2008-12-28 21 views
8

readonly numaralı bir referans türü değişkeni var, çünkü başvuru hiçbir zaman değişmiyor, yalnızca özellikleri. volatile değiştiricisini eklemeyi denediğimde, her iki değiştiricinin de aynı değişkene uygulanmasına izin vermeyeceği uyarısında bulundu. Ama bence uçuculuğa ihtiyacım var çünkü özelliklerini okurken problemleri önbelleğe almak istemiyorum. Ben bir şey eksik miyim? Yoksa derleyici yanlış mı?Neden salt okunur ve uçucu değiştiriciler karşılıklı olarak münhasırdır?

Güncelleştirme Martin aşağıdaki yorumlardan birinde belirtildiği gibi: Hem salt okunur hem de uçucu değiştiriciler, başvuru tipi nesneler söz konusu olduğunda, nesnenin özelliklerine değil, yalnızca başvuruma uygulanır. Kaybettiğim şey buydu, bu yüzden derleyici haklı.

class C 
{ 
    readonly volatile string s; // error CS0678: 'C.s': a field cannot be both volatile and readonly 
} 
+0

Derleyici [potansiyel olarak yanlış] (http://stackoverflow.com/q/39004125/1149773) (her ne kadar belirli senaryonuz için olmasa da). – Douglas

cevap

14

Ne readonly ne de volatile değiştiricileri giricidir. Nesnenin özelliklerine değil, referansın kendisine uygulanırlar.

readonly anahtar sözcüğü, değişkeni başlatıldıktan sonra değişemeyeceğini ve zorladığını belirtir. Değişken, referansın depolandığı küçük bellek yığınıdır.

volatile anahtar sözcüğü, derleyiciye, bir değişkenin içeriğinin birden fazla iş parçacığı tarafından değiştirilebileceğini bildirir. Bu, derleyicinin eşzamanlı erişimde sorunlara yol açabilecek optimizasyonları (değişkenin değerini bir kayıt içine okuma ve bu değeri birkaç komutta kullanma gibi) kullanmasını engeller. Yine, bu sadece referansın depolandığı küçük bellek parçasını etkiler.

Bu şekilde uygulandıklarında, bunların karşılıklı olarak münhasır olduklarını görebilirsiniz. Eğer bir şey okunduğunda (sadece bir kez, başlatma veya yapım aşamasında yazılabilir), o zaman aynı zamanda uçucu olamaz (herhangi bir zamanda birden fazla iş parçacığı ile yazılabilir).

önbelleğe alma sorunları, IIRC ilgiye gelince

, derleyici bir özellik çağrısının sonucunu önbelleğe alabilir ne zaman oldukça sıkı kurallar vardır. 'un bir yöntem çağrısı olduğunu ve onun değerini önbelleğe almak ve onu yeniden çağırmak için oldukça ağır bir optimizasyon (derleyicinin stand-point noktasından) olduğunu unutmayın. Kendini çok fazla endişelendirmen gereken bir şey olduğunu düşünmüyorum.

+1

Özellikler saklanamaz olabilir (Bilmem), ancak destek alanları kesinlikle. Alanlar uçucu olarak işaretlenmelidir. – configurator

+0

Bu yanıt, OP'nin sorusunu doğru olarak ele alır, ancak yanıltıcı bir ifade içerir: "Uçucu anahtar sözcüğü, derleyiciye, bir değişkenin içeriğinin birden fazla iş parçacığı tarafından değiştirilebileceğini bildirir." Bu sadece kısmen doğrudur; volatile anahtar sözcüğü, derleyiciye, değişimin sadece bir kez gerçekleştirilse bile, bir değişkenin içeriğinin eşzamanlı olarak birden çok ileti tarafından değiştirilebileceğini * veya okuyabileceğini söyler. Ben de bu sorunu kapsayan benzer bir soru sordum: [C# dil kusuru: uçucu ve salt okunur özel olmamalıdır] (http://stackoverflow.com/q/39004125/1149773). – Douglas

+0

Bildirimin yanıltıcı olduğunu düşünmüyorum. Belki de bir derleyicinin, bir iş parçacığını okurken başka bir iş parçacığı tarafından değiştirilebileceğini söylemesi daha doğru olurdu, ama sanırım * bu, daha fazla açıklama yapmadan daha fazla yanıltıcıdır. İplik senkronizasyonu sağlamak için “volatile” gereklidir. Sanırım ifadelerim kavramı açık bir şekilde açıklıyor ve bir sonraki cümle temel bir anlayış için yeterince detay veriyor. Sorununuz, .NET'in başlatma davranışının ilginç bir incelemesidir, ancak bundan vazgeçmez. –

1

Yalnızca bir nesne ilk oluşturulduğunda salt okunur bir alan yazılabilir. Bu nedenle, CPU üzerinde herhangi bir önbellekleme sorunu olmayacaktır çünkü alanın değişmez ve değişmesi mümkün değildir.

+0

Mantığınızı anlıyorum ama katılmıyorum. Bir nesne readonly olabilir ve özellikleri ile hala değişmez, çünkü özellikleri salt okunur değildir. Bu durumda salt okunur özellik, yalnızca değişkeni başka bir nesneye atamayı engeller. En azından öğrendiklerimden anladığım şey buydu. –

+2

@Vernict: Okunabilir ve uçucu değiştiriciler, yalnızca nesnenin içeriği değil, referansı (veya bool, int gibi atomik değerler durumunda değeri) korurlar! Bu tamamen farklı bir konu. –

0

Referansın kendisi iş parçacığı olabilir, ancak özellikleri değişmeyebilir. İki iş parçacığının eşzamanlı olarak, içinde numaralı başvuru nesnesinde yineleme gerçekleştirmeye çalıştığı durumlarda ne olacağını düşünün.

+0

Ancak, salt okunur ve uçucu olmayan şeylerin korunma amaçlı bir amacı yoktur. Yine de senkronizasyon ile çözmen gereken bir şey. –

+0

@Charlie, nesnenin uçucu olsa bile, özelliklerinin uçuculuğunu garanti etmediğini mi söylüyorsunuz? –

+0

@Martin C, çok doğru. @Vernicht, Anladığım kadarıyla, evet. Alanlarınızın ve özelliklerin iplik güvenliğini garanti etmesini sağlamanız gerekir. –

İlgili konular