Jakie jest zastosowanie zmiennej statycznej w C #? Kiedy go używać? Dlaczego nie mogę zadeklarować zmiennej statycznej wewnątrz metody?

106

Szukałem o zmiennych statycznych w C #, ale nadal nie rozumiem, do czego służy. Ponadto, jeśli spróbuję zadeklarować zmienną wewnątrz metody, nie da mi to pozwolenia. Czemu?

Widziałem kilka przykładów dotyczących zmiennych statycznych. Widziałem, że nie musimy tworzyć instancji klasy, aby uzyskać dostęp do zmiennej, ale to nie wystarczy, aby zrozumieć, do czego służy i kiedy należy jej używać.

Druga sprawa

class Book
{
    public static int myInt = 0;
}

public class Exercise
{
    static void Main()
    {
        Book book = new Book();

        Console.WriteLine(book.myInt); // Shows error. Why does it show me error?
                                       // Can't I access the static variable 
                                       // by making the instance of a class?

        Console.ReadKey();
    }
}
Kartik Patel
źródło
4
Może masz na myśli „pole statyczne”?
Dennis
Tak jak deklarujemy w klasie static int i = 5
Kartik Patel
3
VB.NET obsługuje lokalne zmienne statyczne. Musieli to zaimplementować, aby zachować zgodność z vb. Ilość generowanego kodu jest ogromna , lokalne statystyki są trudne, ponieważ nie są bezpieczne dla wątków. Pola również nie są bezpieczne dla wątków, ale wszyscy tego oczekują.
Hans Passant
nie zapomnij oznaczyć odpowiedzi jako zaakceptowanej, jeśli otrzymałeś
żądane
3
Dostęp do zmiennych / metod statycznych można uzyskać poprzez typ (w tym przypadku Book) no poprzez instancję ( book), więc łatwiejszym rozwiązaniem jest Book.myInt.
Jaider

Odpowiedzi:

171

staticZmienna wartość dzieli go wśród wszystkich instancji klasy.

Przykład bez deklarowania go jako statyczny:

public class Variable
{
    public int i = 5;
    public void test()
    {
        i = i + 5;
        Console.WriteLine(i);
    }
}


public class Exercise
{
    static void Main()
    {
        Variable var = new Variable();
        var.test();
        Variable var1 = new Variable();
        var1.test();
        Console.ReadKey();
    }
}

Wyjaśnienie: Jeśli spojrzysz na powyższy przykład, po prostu deklaruję intzmienną. Kiedy uruchomię ten kod, dane wyjściowe będą 10i 10. To proste.

Spójrzmy teraz na zmienną statyczną tutaj; Deklaruję zmienną jako static.

Przykład ze zmienną statyczną:

public class Variable
{
    public static int i = 5;
    public void test()
    {
        i = i + 5;
        Console.WriteLine(i);
    }
}


public class Exercise
{
    static void Main()
    {
        Variable var = new Variable();
        var.test();
        Variable var1 = new Variable();
        var1.test();
        Console.ReadKey();
    }
}

Teraz, gdy uruchomię powyższy kod, dane wyjściowe będą 10i 15. Zatem wartość zmiennej statycznej jest wspólna dla wszystkich instancji tej klasy.

Kartik Patel
źródło
9
@Pranay: Tak, to lepiej, ale jeśli pokażesz mi przykład, który pokazuję powyżej, może być lepszy dla mnie i innych ... w każdym razie dobry wysiłek ....
Kartik Patel
1
Jest statyczny dla klasy, tj. Jego wartość pozostaje wierna klasie z wartością przechowywaną w jego ... czekaj na to ... class
chwi
Mówisz, że zmienna statyczna jest wspólna dla wszystkich instancji klasy ... ale co, jeśli nie ma instancji? Czy nadal możesz ustawić zmienną? Czy można przechowywać dane dynamiczne w klasie statycznej?
Kokodoko
@Kokodoko, nawet jeśli nie ma instancji, z pewnością możesz ustawić zmienną. To definiuje jego statyczny charakter
Ladmerc
33

C # w ogóle nie ma zmiennych statycznych . Pole statyczne można zadeklarować w określonej definicji typu za pośrednictwem języka C #. Pole statyczne to stan współdzielony ze wszystkimi instancjami określonego typu. W związku z tym zakres pola statycznego jest pełny. Dlatego nie możesz zadeklarować pola statycznego w metodzie - metoda jest sama w sobie zakresem, a elementy zadeklarowane w metodzie muszą być niedostępne za granicą metody.

Dennis
źródło
5
Cóż, w dokumentacji jest to określone jako „Pole zadeklarowane za pomocą modyfikatora statycznego nazywane jest zmienną statyczną”. msdn.microsoft.com/en-us/library/aa691162(v=vs.71).aspx Ale masz rację co do reszty wyjaśnienia.
Teoman shipahi
19

zmienne statyczne są używane, gdy wymagana jest tylko jedna kopia zmiennej. więc jeśli zadeklarujesz zmienną wewnątrz metody, nie ma zastosowania takiej zmiennej, staje się lokalna tylko do działania.

przykładem jest statyka

class myclass
{
    public static int a = 0;
}

Zmienne zadeklarowane jako statyczne są zwykle współużytkowane we wszystkich wystąpieniach klasy.

Zmienne zadeklarowane jako statyczne są zwykle współużytkowane we wszystkich wystąpieniach klasy. Podczas tworzenia wielu instancji klasy VariableTest Ta zmienna stała jest wspólna dla nich wszystkich. Zatem w dowolnym momencie w stałej zmiennej będzie tylko jedna wartość ciągu.

Ponieważ istnieje tylko jedna kopia zmiennej dostępna dla wszystkich instancji, kod this.permament spowoduje błędy kompilacji, ponieważ można sobie przypomnieć, że this.variablename odnosi się do nazwy zmiennej instancji. W związku z tym dostęp do zmiennych statycznych należy uzyskać bezpośrednio, jak wskazano w kodzie.

Pranay Rana
źródło
czy możesz wyjaśnić na przykładzie?
Kartik Patel
ale jeśli utworzę instancję klasy, nie będę w stanie uzyskać dostępu do zmiennej statycznej. dlaczego? Mogę uzyskać dostęp do zmiennej statycznej przez nazwę klasy. zmienna tylko nie przez utworzenie instancji klasy .......... ......
Kartik Patel
@Kartik Patel, ponieważ musisz użyć nazwy klasy, aby uzyskać dostęp do statycznego myInt. Dlaczego tak się dzieje, nie wiem. Ale powiedziałbym, że jest to o wiele jaśniejsze, ponieważ chcesz uzyskać dostęp do statycznej części klasy, nie jest statyczne, jeśli potrzebujesz instancji, aby uzyskać do niej dostęp.
przestój w
@dowhilefor: Ale jak wspomniałeś powyżej, „Zmienne zadeklarowane jako statyczne są często współdzielone we wszystkich wystąpieniach klasy”. więc jakie jest to znaczenie?
Kartik Patel
@Kartik Patel nie możesz uzyskać dostępu do zmiennej z zewnątrz za pomocą instancji, ale zawsze możesz użyć zmiennej statycznej wewnątrz swojej klasy, a następnie jest ona udostępniona we wszystkich instancjach. Również nie ja udzieliłem tej odpowiedzi, tylko ją komentuję.
przestój w
9

Kilka przykładów ze świata rzeczywistego dla zmiennych statycznych:

budowanie klasy, w której można uzyskać zakodowane wartości dla swojej aplikacji. Podobny do wyliczenia, ale z większą elastycznością co do typu danych.

public static class Enemies
{
    public readonly static Guid Orc = new Guid("{937C145C-D432-4DE2-A08D-6AC6E7F2732C}");
}

Powszechnie znany singleton, który pozwala kontrolować posiadanie dokładnie jednej instancji klasy. Jest to bardzo przydatne, jeśli chcesz mieć do niego dostęp w całej aplikacji, ale nie chcesz go przekazywać do każdej klasy tylko po to, aby ta klasa mogła z niego korzystać.

public sealed class TextureManager
    {
        private TextureManager() {}
        public string LoadTexture(string aPath);

        private static TextureManager sInstance = new TextureManager();

        public static TextureManager Instance
        {
            get { return sInstance; }
        }
    }

i tak można nazwać menedżera tekstur

TextureManager.Instance.LoadTexture("myImage.png");

O ostatnim pytaniu: odnosisz się do błędu kompilatora CS0176 . Próbowałem znaleźć więcej informacji na ten temat, ale mogłem tylko dowiedzieć się, co ma do powiedzenia msdn:

Statyczną metodę, pole, właściwość lub zdarzenie można wywołać w klasie, nawet jeśli nie utworzono żadnego wystąpienia tej klasy. Jeśli zostaną utworzone jakiekolwiek wystąpienia klasy, nie można ich użyć do uzyskania dostępu do statycznego elementu członkowskiego. Istnieje tylko jedna kopia statycznych pól i zdarzeń, a statyczne metody i właściwości mogą uzyskiwać dostęp tylko do pól statycznych i zdarzeń statycznych.

w dółhilefor
źródło
5

Zmienne statyczne są używane, gdy wymagana jest tylko jedna ich kopia. Wyjaśnię to na przykładzie:

class circle
{
    public float _PI =3.14F;
    public int Radius;

    public funtionArea(int radius)
    {
        return this.radius * this._PI      
    }
}
class program
{
    public static void main()
    {
        Circle c1 = new Cirle();
        float area1 = c1.functionRaduis(5);
        Circle c2 = new Cirle();
        float area2 = c1.functionRaduis(6);
    }
}

Teraz stworzyliśmy 2 instancje dla naszego classokręgu, czyli _PI tworzone są 2 zestawy kopii wraz z innymi zmiennymi. Powiedzmy, że jeśli mamy wiele instancji tej klasy, _PIutworzonych zostanie wiele kopii zajmujących pamięć. Dlatego w takich przypadkach lepiej jest polubić takie zmienne _PI statici operować na nich.

class circle
{
    static float _PI =3.14F;
    public int Radius;

    public funtionArea(int radius)
    {
        return this.radius * Circle._PI      
    }
}
class program
{
    public static void main()
    {
        Circle c1 = new Cirle();
        float area1 = c1.functionRaduis(5);
        Circle c2 = new Cirle();
        float area2 = c1.functionRaduis(6);
    }
}

Teraz bez względu na to, ile wystąpień jest utworzonych dla classkoła, istnieje tylko jedna kopia zmiennej _PIzapisującej naszą pamięć.

Tom Hardy
źródło
4

Klasy statyczne nie wymagają tworzenia obiektu tej klasy / tworzenia ich instancji, można poprzedzić słowo kluczowe C # static przed nazwą klasy, aby była statyczna.

Pamiętaj: nie tworzymy instancji klasy Console, klasy String, klasy Array.

class Book
{
    public static int myInt = 0;
}

public class Exercise
{
    static void Main()
    {
        Book book = new Book();
       //Use the class name directly to call the property myInt, 
      //don't use the object to access the value of property myInt

        Console.WriteLine(Book.myInt);

        Console.ReadKey();

    }
}
Kunal Mukherjee
źródło
bardzo dobra obserwacja, ponieważ jeśli spróbujesz użyć obiektu do uzyskania dostępu do wartości właściwości myInt the, otrzymasz błąd: static void Main () {Book book = new Book (); // to daje błąd: book.myInt = 5;
leonidaa

2

Zaczynając od tego przykładu @Kartik Patel, trochę się zmieniłem, może teraz jest bardziej jasne o zmiennej statycznej

 public class Variable
    {
        public static string StaticName = "Sophia ";
        public string nonStName = "Jenna ";
        public void test()
        {
            StaticName = StaticName + " Lauren"; 
            Console.WriteLine("  static ={0}",StaticName);
            nonStName = nonStName + "Bean ";
            Console.WriteLine("  NeStatic neSt={0}", nonStName);

        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Variable var = new Variable();
            var.test();
            Variable var1 = new Variable();
            var1.test();
            Variable var2 = new Variable();
            var2.test();
            Console.ReadKey();

        }
    }

Output 
  static =Sophia  Lauren
  NeStatic neSt=Jenna Bean
  static =Sophia  Lauren Lauren
  NeStatic neSt=Jenna Bean
  static =Sophia  Lauren Lauren Lauren
  NeStatic neSt=Jenna Bean
  1. Zmienna klasy VS Zmienna wystąpienia w języku C #

    Statyczne składowe klasy C # OR Zmienna klasy

    class A
    {
        // Class variable or " static member variable"  are declared with 
        //the "static " keyword
    
        public static int i=20;
        public int j=10;         //Instance variable 
        public static string s1="static class variable"; //Class variable 
        public string s2="instance variable";        // instance variable 
    }
    class Program
    {
        static void Main(string[] args)
        {
            A obj1 = new A();
    
            // obj1 instance variables 
            Console.WriteLine("obj1 instance variables ");
            Console.WriteLine(A.i);
            Console.WriteLine(obj1.j);
            Console.WriteLine(obj1.s2);
            Console.WriteLine(A.s1);
    
            A obj2 = new A();
    
            // obj2 instance variables 
            Console.WriteLine("obj2 instance variables ");
            Console.WriteLine(A.i);
            Console.WriteLine(obj2.j);
            Console.WriteLine(obj2.s2);
            Console.WriteLine(A.s1);
    
            Console.ReadKey();
    
        }
    
    
    }

    }

wprowadź opis obrazu tutaj wprowadź opis obrazu tutaj wprowadź opis obrazu tutaj wprowadź opis obrazu tutaj

https://en.wikipedia.org/wiki/Class_variable

https://en.wikipedia.org/wiki/Instance_variable

https://en.wikipedia.org/wiki/Static_variable

https://javaconceptoftheday.com/class-variables-and-instance-variables-in-java/?fbclid=IwAR1_dtpHzg3bC5WlGQGdgewaTvuOI6cwVeFUtTV8IZuGTj1qH5PmKGwX0yM

https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/static-classes-and-static-class-members

leonidaa
dokładnie, zobacz przykład @Kunal Mukherjee z góry
leonidaa
1

Elementy członkowskie danych i elementy członkowskie funkcji, które działają na wystąpieniu typu, nazywane są elementami członkowskimi wystąpienia. Metoda ToString int (na przykład) to przykłady elementów członkowskich instancji. Domyślnie członkowie są członkami instancji. Elementy członkowskie danych i elementy członkowskie funkcji, które nie działają na wystąpieniu typu, ale raczej na samym typie, muszą być oznaczone jako statyczne. Metody Test.Main i Console.WriteLine są metodami statycznymi. Klasa Console jest w rzeczywistości klasą statyczną, co oznacza, że ​​wszystkie jej elementy członkowskie są statyczne. W rzeczywistości nigdy nie tworzysz instancji konsoli - jedna konsola jest współdzielona przez całą aplikację.

MichaelY
źródło
1

W odpowiedzi na pytanie „kiedy go używać?” pytanie:

Często używam zmiennej statycznej (klasy), aby przypisać unikalny identyfikator instancji do każdej instancji klasy. Używam tego samego kodu na wszystkich zajęciach, jest to bardzo proste:

//Instance ID ----------------------------------------
    // Class variable holding the last assigned IID
    private static int xID = 0;
    // Lock to make threadsafe (can omit if single-threaded)
    private static object xIDLock = new object();
    // Private class method to return the next unique IID 
    //  - accessible only to instances of the class
    private static int NextIID()                    
    {
        lock (xIDLock) { return ++xID; }
    }
    // Public class method to report the last IID used 
    // (i.e. the number of instances created)
    public static int LastIID() { return xID; }
    // Instance readonly property containing the unique instance ID
    public readonly int IID = NextIID();
//-----------------------------------------------------

To ilustruje kilka punktów dotyczących zmiennych statycznych i metod:

  1. Statyczne zmienne i metody są skojarzone z klasą, a nie z żadną konkretną instancją klasy.
  2. Metodę statyczną można wywołać w konstruktorze instancji - w tym przypadku metoda statyczna NextIID jest używana do zainicjowania właściwości IID tylko do odczytu, która jest unikalnym identyfikatorem dla tej instancji.

Uważam to za przydatne, ponieważ tworzę aplikacje, w których używane są roje obiektów i dobrze jest być w stanie śledzić, ile zostało utworzonych, a także śledzić / przeszukiwać poszczególne instancje.

Używam również zmiennych klas do śledzenia takich rzeczy, jak sumy i średnie właściwości instancji, które mogą być raportowane w czasie rzeczywistym. Myślę, że klasa to dobre miejsce do przechowywania podsumowania informacji o wszystkich instancjach klasy.

JohnRC
źródło
0

Spróbuj zadzwonić bezpośrednio z nazwą klasy Book.myInt

Arnold Parge
źródło
dokładnie, zobacz przykład @Kunal Mukherjee z góry
leonidaa
0

W porównaniu ze zmiennymi sesyjnymi, zmienne statyczne będą miały taką samą wartość dla wszystkich użytkowników, którzy biorą pod uwagę, że używam aplikacji wdrożonej na serwerze. Jeśli dwóch użytkowników uzyskuje dostęp do tej samej strony aplikacji, zmienna statyczna będzie przechowywać najnowszą wartość i ta sama wartość zostanie dostarczona obu użytkownikom w przeciwieństwie do zmiennych sesji, które są różne dla każdego użytkownika. Tak więc, jeśli chcesz mieć coś wspólnego i tego samego dla wszystkich użytkowników, w tym wartości, które mają być używane w kodzie aplikacji, użyj tylko statycznego.

pratham gn
źródło
0

Nie musisz tworzyć instancji obiektu, ponieważ yau użyje zmiennej statycznej: Console.WriteLine (Book.myInt);

Mehran Sarrafi
źródło
-1

Zmienna statyczna zachowuje swoją poprzednią wartość aż do zakończenia programu. Statyczny jest używany przez bezpośrednie wywołanie class_Name.Method () lub class_Name.Property. Nie jest potrzebne żadne odniesienie do obiektu. Najpopularniejszym zastosowaniem statycznego jest klasa Math w języku C #. Math.Sin (), Math.Cos (), Math.Sqrt ().

Md Shahriar
źródło