¿Cuál es el uso de la variable estática en C #? ¿Cuándo usarlo? ¿Por qué no puedo declarar la variable estática dentro del método?

106

He buscado sobre variables estáticas en C #, pero todavía no entiendo cuál es su uso. Además, si intento declarar la variable dentro del método, no me dará permiso para hacerlo. ¿Por qué?

He visto algunos ejemplos sobre las variables estáticas. He visto que no necesitamos crear una instancia de la clase para acceder a la variable, pero eso no es suficiente para entender cuál es su uso y cuándo usarlo.

Segunda cosa

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
fuente
4
¿Te refieres a "campo estático"?
Dennis
Como declaramos en clase static int i = 5
Kartik Patel
3
VB.NET admite variables estáticas locales. Tuvieron que implementarlo para seguir siendo compatible con vb. La cantidad de código que genera es enorme , las estadísticas locales son difíciles porque no son seguras para subprocesos. Los campos tampoco son seguros para subprocesos, pero todo el mundo lo espera.
Hans Passant
no olvide marcar la respuesta como aceptada si obtuvo la información que desea ...
Pranay Rana
3
Puede acceder a variables / métodos estáticos a través del tipo (en este caso Book) no a través de una instancia ( book), por lo que la solución más fácil es Book.myInt.
Jaider

Respuestas:

171

Una staticvariable comparte su valor entre todas las instancias de la clase.

Ejemplo sin declararlo estático:

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

Explicación: si miras el ejemplo anterior, simplemente declaro la intvariable. Cuando ejecuto este código, la salida será 10y 10. Es sencillo.

Ahora veamos la variable estática aquí; Declaro la variable como static.

Ejemplo con variable estática:

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

Ahora, cuando ejecuto el código anterior, la salida será 10y 15. Entonces, el valor de la variable estática se comparte entre todas las instancias de esa clase.

Kartik Patel
fuente
9
@Pranay: Sí, eso es mejor, pero si me muestra el ejemplo que muestro arriba, podría ser mejor para mí y para los demás ... de todos modos, buen esfuerzo ...
Kartik Patel
1
Es estático para la clase, es decir, su valor permanece fiel a la clase con su valor almacenado en su ... espere ... clase
chwi
Dice que una variable estática se comparte entre todas las instancias de la clase ... pero ¿y si no hay instancias? ¿Todavía puedes establecer una variable? ¿Está permitido almacenar datos dinámicos en una clase estática?
Kokodoko
@Kokodoko, incluso si no hay una instancia, seguramente puede establecer la variable. Eso define su naturaleza estática
Ladmerc
33

C # no tiene variables estáticas en absoluto. Puede declarar un campo estático en la definición de tipo particular a través de C #. El campo estático es un estado, compartido con todas las instancias de un tipo particular. Por tanto, el alcance del campo estático es de tipo completo. Es por eso que no puede declarar un campo estático dentro de un método: el método es un ámbito en sí mismo, y los elementos declarados en un método deben ser inaccesibles sobre el borde del método.

Dennis
fuente
5
Bueno, en la documentación se indica como "Un campo declarado con el modificador estático se llama variable estática". msdn.microsoft.com/en-us/library/aa691162(v=vs.71).aspx Pero tienes razón en el resto de la explicación.
Teoman shipahi
19

Las variables estáticas se utilizan cuando solo se requiere una copia de la variable. por lo que si declara una variable dentro del método, no hay uso de dicha variable, se vuelve local para funcionar solo.

ejemplo de estática es

class myclass
{
    public static int a = 0;
}

Las variables declaradas estáticas se comparten comúnmente en todas las instancias de una clase.

Las variables declaradas estáticas se comparten comúnmente en todas las instancias de una clase. Cuando crea varias instancias de la clase VariableTest, esta variable permanente se comparte entre todas ellas. Por lo tanto, en cualquier momento dado, solo habrá un valor de cadena contenido en la variable permanente.

Dado que solo hay una copia de la variable disponible para todas las instancias, el código this.permament dará lugar a errores de compilación porque se puede recordar que this.variablename se refiere al nombre de la variable de instancia. Por lo tanto, se debe acceder directamente a las variables estáticas, como se indica en el código.

Pranay Rana
fuente
¿puede explicar con un ejemplo?
Kartik Patel
pero si hago la instancia de una clase, entonces no puedo acceder a la variable estática. ¿Por qué? Puedo acceder a la variable estática por classname.variable solo, no haciendo la instancia de una clase .......... ......
Kartik Patel
@Kartik Patel porque tienes que usar el nombre de la clase para acceder al myInt estático. Por qué es así, no lo sé. Pero diría que es mucho más claro porque desea acceder a una parte estática de la clase, no es estática si necesita una instancia para acceder a ella.
dowhilefor
@dowhilefor: Pero como mencionaste anteriormente, "las variables declaradas estáticas se comparten comúnmente en todas las instancias de una clase". entonces, ¿cuál es el significado de esto?
Kartik Patel
@Kartik Patel no puede acceder a la variable desde el exterior con una instancia, pero siempre puede usar la variable estática dentro de su clase y luego se comparte en todas las instancias. Además, no fui yo quien dio esta respuesta, solo lo estoy comentando.
dowhilefor
9

Algunos ejemplos del "mundo real" para variables estáticas:

crear una clase en la que pueda alcanzar valores codificados para su aplicación. Similar a una enumeración, pero con más flexibilidad en el tipo de datos.

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

El singleton ampliamente conocido, esto permite controlar tener exactamente una instancia de una clase. Esto es muy útil si desea acceder a él en toda su aplicación, pero no pasarlo a todas las clases solo para permitir que esta clase lo use.

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

        private static TextureManager sInstance = new TextureManager();

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

y así es como llamarías al administrador de texturas

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

Acerca de su última pregunta: se refiere al error del compilador CS0176 . Traté de encontrar más información sobre eso, pero solo pude encontrar lo que el msdn tenía que decir al respecto:

Un método, campo, propiedad o evento estático es invocable en una clase incluso cuando no se ha creado ninguna instancia de la clase. Si se crean instancias de la clase, no se pueden utilizar para acceder al miembro estático. Solo existe una copia de los campos y eventos estáticos, y los métodos y propiedades estáticos solo pueden acceder a los campos y eventos estáticos.

dowhilefor
fuente
5

Las variables estáticas se utilizan cuando solo se requiere una copia. Déjame explicarte esto con un ejemplo:

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

Ahora aquí hemos creado 2 instancias para nuestro classcírculo, es decir, se crean 2 conjuntos de copias de _PI junto con otras variables. Entonces, digamos que si tenemos muchas instancias de esta clase _PI, se crearán múltiples copias ocupando memoria. Entonces, en tales casos, es mejor hacer que tales variables sean similares _PI staticy operar sobre ellas.

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

Ahora, no importa cuántas instancias se hagan para el classcírculo, solo existe una copia de la variable que _PIguarda nuestra memoria.

Tom Hardy
fuente
4

Las clases estáticas no requieren que cree un objeto de esa clase / instanciarlas, puede prefijar la palabra clave C # estática delante del nombre de la clase, para hacerlo estático.

Recuerde: no estamos creando una instancia de la clase Console, la clase String, la clase 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
fuente
muy buena observación porque si intenta utilizar el objeto para acceder al valor de la propiedad myInt, obtendrá un error: static void Main () {Book book = new Book (); // esto le da error: book.myInt = 5;
leonidaa

2

A partir de este ejemplo de @Kartik Patel, he cambiado un poco, tal vez ahora sea más claro acerca de la variable estática

 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. Variable de clase VS variable de instancia en C #

    Miembros de clase estática C # OR variable de clase

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

    }

ingrese la descripción de la imagen aquí ingrese la descripción de la imagen aquí ingrese la descripción de la imagen aquí ingrese la descripción de la imagen aquí

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
exactamente, vea el ejemplo de @Kunal Mukherjee de arriba
leonidaa
1

Los miembros de datos y los miembros de función que operan en la instancia del tipo se denominan miembros de instancia. El método ToString de int (por ejemplo) son ejemplos de miembros de instancia. De forma predeterminada, los miembros son miembros de instancia. Los miembros de datos y los miembros de función que no operan en la instancia del tipo, sino en el tipo en sí, deben marcarse como estáticos. Los métodos Test.Main y Console.WriteLine son métodos estáticos. La clase Console es en realidad una clase estática, lo que significa que todos sus miembros son estáticos. En realidad, nunca crea instancias de una consola: una consola se comparte en toda la aplicación.

MichaelY
fuente
1

En respuesta al "¿cuándo usarlo?" pregunta:

A menudo uso una variable estática (clase) para asignar un ID de instancia único a cada instancia de una clase. Utilizo el mismo código en todas las clases, es muy simple:

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

Esto ilustra un par de puntos sobre las variables y métodos estáticos:

  1. Las variables y métodos estáticos están asociados con la clase, no con una instancia específica de la clase.
  2. Se puede llamar a un método estático en el constructor de una instancia; en este caso, el método estático NextIID se usa para inicializar la propiedad de solo lectura IID, que es el ID único para esta instancia.

Encuentro esto útil porque desarrollo aplicaciones en las que se utilizan enjambres de objetos y es bueno poder rastrear cuántos se han creado y rastrear / consultar instancias individuales.

También utilizo variables de clase para rastrear cosas como totales y promedios de propiedades de las instancias que se pueden informar en tiempo real. Creo que la clase es un buen lugar para guardar información resumida sobre todas las instancias de la clase.

JohnRC
fuente
0

Intente llamarlo directamente con el nombre de la clase Book.myInt

Arnold Parge
fuente
exactamente, vea el ejemplo de @Kunal Mukherjee de arriba
leonidaa
0

En comparación con las variables de sesión, las variables estáticas tendrán el mismo valor para todos los usuarios considerando que estoy usando una aplicación implementada en el servidor. Si dos usuarios acceden a la misma página de una aplicación, entonces la variable estática tendrá el último valor y se proporcionará el mismo valor a ambos usuarios, a diferencia de las variables de sesión que son diferentes para cada usuario. Por lo tanto, si desea algo común e igual para todos los usuarios, incluidos los valores que se supone que deben usarse en el código de la aplicación, use solo static.

pratham gn
fuente
0

No necesitas crear una instancia de un objeto, porque vas a usar una variable estática: Console.WriteLine (Book.myInt);

Mehran Sarrafi
fuente
-1

La variable estática conserva su valor anterior hasta la salida del programa. Static se usa llamando directamente class_Name.Method () o class_Name.Property. No se necesita ninguna referencia de objeto. El uso más popular de static es la clase Math de C #. Math.Sin (), Math.Cos (), Math.Sqrt ().

Md Shahriar
fuente