Какая польза от статической переменной в C #? Когда это использовать? Почему я не могу объявить статическую переменную внутри метода?


106

Я искал статические переменные в C #, но до сих пор не понимаю, в чем их смысл. Кроме того, если я попытаюсь объявить переменную внутри метода, это не даст мне на это разрешения. Зачем?

Я видел несколько примеров статических переменных. Я видел, что нам не нужно создавать экземпляр класса для доступа к переменной, но этого недостаточно, чтобы понять, как он используется и когда его использовать.

Вторая вещь

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();
    }
}

4
Может быть вы имеете в виду «статическое поле»?
Деннис

Как мы объявляем в классе static int i = 5
Kartik Patel

3
VB.NET поддерживает локальные статические переменные. Им пришлось реализовать его, чтобы оставаться совместимым с vb. Объем кода, который он генерирует, огромен , локальная статика затруднена, поскольку не является потокобезопасной. Поля тоже не являются потокобезопасными, но этого все ожидают.
Ханс Пассан

не забудьте пометить ответ как принятый, если вы получили
нужную

3
Вы можете получить доступ к статическим переменным / методам через тип (в данном случае Book) no через instance ( book), так что это более простое решение Book.myInt.
Jaider

Ответы:


171

staticПеременная разделяет значение его среди всех экземпляров класса.

Пример без объявления статическим:

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();
    }
}

Объяснение: Если вы посмотрите на приведенный выше пример, я просто объявляю intпеременную. Когда я запускаю этот код, на выходе будет 10и 10. Это просто.

Теперь давайте посмотрим на статическую переменную здесь; Я объявляю переменную как static.

Пример со статической переменной:

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();
    }
}

Теперь, когда я запускаю приведенный выше код, на выходе будет 10и 15. Таким образом, значение статической переменной распределяется между всеми экземплярами этого класса.


9
@Pranay: Да, это лучше, но если вы покажете мне пример, который я показываю выше, чем он может быть лучше для меня и других .... в любом случае хорошие усилия ....
Картик Патель

1
Он статичен для класса, т. Е. Его значение остается верным классу с его значением, хранящимся в его ... подождите ... class
chwi

Вы говорите, что статическая переменная используется всеми экземплярами класса ... но что, если экземпляров нет? Вы все еще можете установить переменную? Можно ли хранить динамические данные в статическом классе?
Kokodoko,

@Kokodoko, даже если экземпляра нет, вы обязательно можете установить переменную. Это определяет его статический характер
Ladmerc

33

В C # вообще нет статических переменных . Вы можете объявить статическое поле в определении конкретного типа через C #. Статическое поле - это состояние, общее для всех экземпляров определенного типа. Следовательно, область статического поля - весь тип. Вот почему вы не можете объявить статическое поле внутри метода - метод сам по себе является областью действия, а элементы, объявленные в методе, должны быть недоступны за границей метода.


5
В документации это указано как «Поле, объявленное с помощью модификатора static, называется статической переменной». msdn.microsoft.com/en-us/library/aa691162(v=vs.71).aspx Но вы правы в остальной части объяснения.
Теоман Шипахи,

19

статические переменные используются, когда требуется только одна копия переменной. поэтому, если вы объявляете переменную внутри метода, такая переменная не используется, она становится локальной только для работы.

пример статики

class myclass
{
    public static int a = 0;
}

Переменные, объявленные статическими, обычно используются всеми экземплярами класса.

Переменные, объявленные статическими, обычно используются всеми экземплярами класса. Когда вы создаете несколько экземпляров класса VariableTest, эта постоянная переменная является общей для всех. Таким образом, в любой момент времени в постоянной переменной будет содержаться только одно строковое значение.

Поскольку для всех экземпляров доступна только одна копия переменной, код this.permament приведет к ошибкам компиляции, потому что можно вспомнить, что this.variablename относится к имени переменной экземпляра. Таким образом, статические переменные должны быть доступны напрямую, как указано в коде.


не могли бы вы объяснить на примере?
Kartik Patel

но если я создаю экземпляр класса, тогда я не смогу получить доступ к статической переменной. Почему? Я могу получить доступ к статической переменной с помощью classname.variable, только не создавая экземпляр класса .......... ......
Картик Патель

@Kartik Patel, потому что вам нужно использовать имя класса для доступа к статическому myInt. Почему так, я не знаю. Но я бы сказал, что это намного яснее, потому что вы хотите получить доступ к статической части класса, это не статично, если вам нужен экземпляр для доступа к нему.
dowhile

@dowhilefor: Но, как вы упомянули выше, «переменные, объявленные статическими, обычно используются всеми экземплярами класса». тогда что это значит?
Картик Патель,

@Kartik Patel, вы не можете получить доступ к переменной извне с помощью экземпляра, но вы всегда можете использовать статическую переменную внутри своего класса, а затем она используется во всех экземплярах. И это не я дал этот ответ, я просто комментирую его.
dowhile

9

Некоторые примеры "реального мира" для статических переменных:

создание класса, в котором вы можете достичь жестко запрограммированных значений для своего приложения. Подобно перечислению, но с большей гибкостью в отношении типа данных.

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

Широко известный синглтон, это позволяет контролировать наличие только одного экземпляра класса. Это очень полезно, если вы хотите получить к нему доступ во всем приложении, но не передавать его каждому классу, чтобы этот класс мог его использовать.

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

        private static TextureManager sInstance = new TextureManager();

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

и вот как вы бы назвали менеджер текстур

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

По поводу вашего последнего вопроса: вы имеете в виду ошибку компилятора CS0176 . Я попытался найти больше информации об этом, но смог найти только то, что говорилось об этом в msdn:

Статический метод, поле, свойство или событие могут быть вызваны в классе, даже если экземпляр этого класса не был создан. Если какие-либо экземпляры класса созданы, их нельзя использовать для доступа к статическому члену. Существует только одна копия статических полей и событий, а статические методы и свойства могут обращаться только к статическим полям и статическим событиям.


5

Статические переменные используются, когда требуется только одна их копия. Позвольте мне объяснить это на примере:

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);
    }
}

Теперь мы создали 2 экземпляра для нашего classкруга, то есть созданы 2 набора копий _PI вместе с другими переменными. Скажем, если у нас будет много экземпляров этого класса, _PIбудет создано несколько копий , занимающих память. Поэтому в таких случаях лучше сделать такие переменные похожими _PI staticи оперировать ими.

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);
    }
}

Теперь независимо от того, сколько экземпляров сделано для classкруга, существует только одна копия переменной, _PIсохраняющая нашу память.


4

Статические классы не требуют, чтобы вы создавали объект этого класса / инстанциировали их, вы можете префикс ключевого слова C # static перед именем класса, чтобы сделать его статическим.

Помните: мы не создаем экземпляры класса Console, класса String, класса 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();

    }
}

очень хорошее наблюдение, потому что если вы попытаетесь использовать объект для доступа к значению свойства myInt, вы получите сообщение об ошибке: static void Main () {Book book = new Book (); // это даст вам ошибку: book.myInt = 5;
leonidaa

2

Начиная с этого примера @Kartik Patel, я немного изменил, может быть, теперь стало более ясно о статической переменной

 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. Переменная класса VS переменная экземпляра в C #

    Статические члены класса C # ИЛИ переменная класса

    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();
    
        }
    
    
    }

    }

введите описание изображения здесь введите описание изображения здесь введите описание изображения здесь введите описание изображения здесь

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


1

Члены данных и функции-члены, которые работают с экземпляром типа, называются членами экземпляра. Метод ToString типа int (например) является примерами членов экземпляра. По умолчанию члены являются членами экземпляра. Члены данных и функции-члены, которые работают не с экземпляром типа, а с самим типом, должны быть помечены как статические. Методы Test.Main и Console.WriteLine являются статическими. Класс Console на самом деле является статическим классом, что означает, что все его члены статичны. Фактически вы никогда не создаете экземпляры консоли - одна консоль используется для всего приложения.


1

В ответ на вопрос "когда это использовать?" вопрос:

Я часто использую статическую переменную (класс), чтобы присвоить уникальный идентификатор экземпляра каждому экземпляру класса. Я использую один и тот же код в каждом классе, это очень просто:

//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();
//-----------------------------------------------------

Это иллюстрирует пару моментов, касающихся статических переменных и методов:

  1. Статические переменные и методы связаны с классом, а не с каким-либо конкретным экземпляром класса.
  2. В конструкторе экземпляра можно вызвать статический метод - в этом случае статический метод NextIID используется для инициализации свойства IID только для чтения, которое является уникальным идентификатором для этого экземпляра.

Я считаю это полезным, потому что я разрабатываю приложения, в которых используются рои объектов, и хорошо иметь возможность отслеживать, сколько их было создано, а также отслеживать / запрашивать отдельные экземпляры.

Я также использую переменные класса для отслеживания таких вещей, как итоговые и средние значения свойств экземпляров, о которых можно сообщать в режиме реального времени. Я думаю, что класс - хорошее место для хранения сводной информации обо всех экземплярах класса.



0

При сравнении с переменными сеанса статические переменные будут иметь одинаковое значение для всех пользователей, учитывая, что я использую приложение, развернутое на сервере. Если два пользователя обращаются к одной и той же странице приложения, то статическая переменная будет содержать последнее значение, и одно и то же значение будет предоставлено обоим пользователям, в отличие от переменных сеанса, которые различны для каждого пользователя. Итак, если вам нужно что-то общее и одинаковое для всех пользователей, включая значения, которые предполагается использовать в коде приложения, используйте только static.


0

Вам не нужно создавать экземпляр объекта, потому что yau будет использовать статическую переменную: Console.WriteLine (Book.myInt);


-1

Статическая переменная сохраняет свое предыдущее значение до выхода из программы. Статический используется путем прямого вызова class_Name.Method () или class_Name.Property. Ссылка на объект не требуется. Наиболее популярным использованием static является класс Math в C #. Math.Sin (), Math.Cos (), Math.Sqrt ().

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.