C # 'da Global Değişkenler nasıl kullanılır?


101

Her sınıfın (* .cs) bir örnek referansı olmadan içeriğine erişebilmesi için bir değişkeni nasıl tanımlayabilirim?

Yanıtlar:


124

İçinde C#gerçek global değişkenleri tanımlayamazsınız (herhangi bir sınıfa ait olmadıkları anlamda).

Bununla birlikte, bu özelliği taklit etmeyi bildiğim en basit yaklaşım static class, aşağıdaki gibi a kullanmaktan ibarettir :

public static class Globals
{
    public const Int32 BUFFER_SIZE = 512; // Unmodifiable
    public static String FILE_NAME = "Output.txt"; // Modifiable
    public static readonly String CODE_PREFIX = "US-"; // Unmodifiable
}

Daha sonra tanımlı değerleri kodunuzun herhangi bir yerinde alabilirsiniz (aynısının parçası olması koşuluyla namespace):

String code = Globals.CODE_PREFIX + value.ToString();

Farklı ad alanlarıyla uğraşmak için şunlardan birini yapabilirsiniz:

  • Globalssınıfı belirli bir alana dahil etmeden bildirmek namespace(böylece genel uygulama ad alanına yerleştirilecektir);
  • Değişkenleri diğerinden almak için uygun kullanım yönergesini ekleyin namespace.

@Zarathos sınıfın da statik olması gerekiyor mu?
kosnkov

4
Bu gerekli değil ama neden bunu başlatmanız gerektiğini anlamıyorum.
Tommaso Belluzzo

Artık "küresel" değil, uygulama durumunun bir parçası değil, tanımına göre somutlaştırmanız gerekiyorsa
Viking

Merhaba, sınıftaki statik anahtar kelimeyi yazmazsam fark ne olur? Yalnızca FILE_NAME dizesini statik yaptım, denedim ve yine de benim için çalıştı.
Tomer Cahal

1
Statik öznitelik olmadan sınıfınız başlatılabilir (Globals g = new Globals ()). İçeride açıklanan statik değişkenlerin davranışını değiştirmez, ancak gerçekten kullanışlı görünmüyor.
Tommaso Belluzzo

74

C # 'da global değişken diye bir şey yoktur. Dönem.

İsterseniz statik üyeleriniz olabilir:

public static class MyStaticValues
{
   public static bool MyStaticBool {get;set;}
}

Ben hemfikir olsam da, lütfen C # 'da küresel değişken diye bir şeyin neden olmadığını açıklar mısınız? Sağladığınız bu staticörneğin gerçekten küresel bir değişken olarak kabul edilememesinin iyi bir nedenini düşünmeye çalışıyordum .
cregox

3
@cawas çünkü "küresel değişken" kavramı (hiçbir yerden sarkan, limbo içinde yüzen, herhangi bir sınıfa ait olmayan) OOP'nin doğasına aykırıdır. ve C # kesinlikle nesne yönelimli.
Federico Berasategui

Evet, kabul ettiğim tüm kavram bu. Ancak bu statik üyeyi yaparak bir tür global var oluşturdunuz. Bunun olmadığını söylediğin küresel değişkenden ne kadar farklı? Pratik bir örnek görmek istiyorum.
cregox

1
Ya sorumdan kaçıyorsun ya da net değilim. Ama zaten cevaplandırdım. Burada: stackoverflow.com/a/20010543/274502
cregox

7
Şimdi anlıyorum ki, statik üyeler kavramsal ve pratik olarak küresel değişkenlerdir (belki bu yığın şey hariç , bu yalnızca güvenli olmayan kod yazmadığınız veya yönetilmeyen kodla bir tür yoğun birlikte çalışmadığınız sürece fark yaratır ). Bu yüzden neden birisi " csharp'ta global değişken diye bir şey yoktur " der ki bilmiyorum . Kafamı çok karıştırdı.
cregox

23

Öncelikle, gerçekten global bir değişkene ihtiyacınız olup olmadığını, bunun yerine onu yazılım mimarinizi dikkate almadan açıkça kullanmak yerine inceleyin.

Testi geçtiğini varsayalım. Kullanıma bağlı olarak, Globals'ın yarış koşulları ve diğer birçok "kötü şey" ile hata ayıklaması zor olabilir, onlara bu kadar kötü şeylerle baş etmeye hazır olduğunuz bir açıdan yaklaşmak en iyisidir. Yani,

  1. Tüm bu Global değişkenleri tek bir staticsınıfa sarın (yönetilebilirlik için).
  2. Alanlar (= 'değişkenler') yerine Özellikler'e sahip olun. Bu şekilde, gelecekte Globals'a eşzamanlı yazımlarla ilgili sorunları gidermek için bazı mekanizmalarınız olur.

Böyle bir sınıf için temel taslak şu şekilde olacaktır:

public class Globals
{
    private static bool _expired;
    public static bool Expired 
    {
        get
        {
            // Reads are usually simple
            return _expired;
        }
        set
        {
            // You can add logic here for race conditions,
            // or other measurements
            _expired = value;
        }
    }
    // Perhaps extend this to have Read-Modify-Write static methods
    // for data integrity during concurrency? Situational.
}

Diğer sınıflardan kullanım (aynı ad alanı içinde)

// Read
bool areWeAlive = Globals.Expired;

// Write
// past deadline
Globals.Expired = true;

4

Bunun için kullanışlı bir özellik using static

Başkalarının da söylediği gibi, globalleriniz için bir sınıf oluşturmanız gerekir:

public static class Globals {
    public const float PI = 3.14;
}

Ancak sınıf adını artık statik özelliklerinin önüne yazmamak için bu şekilde içe aktarabilirsiniz:

using static Globals;
[...]
Console.WriteLine("Pi is " + PI);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.