Qual é o uso de variável estática em C #? Quando usar? Por que não posso declarar a variável estática dentro do método?

106

Eu pesquisei sobre variáveis ​​estáticas em C #, mas ainda não estou entendendo seu uso. Além disso, se eu tentar declarar a variável dentro do método, não me dará permissão para fazer isso. Por quê?

Eu vi alguns exemplos sobre as variáveis ​​estáticas. Eu vi que não precisamos criar uma instância da classe para acessar a variável, mas isso não é suficiente para entender o que é seu uso e quando usá-lo.

Segunda coisa

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
fonte
4
Pode ser você quer dizer "campo estático"?
Dennis
Como declaramos na classe static int i = 5
Kartik Patel
3
VB.NET suporta variáveis ​​estáticas locais. Eles tiveram que implementá-lo para permanecer compatível com o vb. A quantidade de código que ele gera é enorme , a estática local é difícil porque não é segura para threads. Os campos também não são seguros para thread, mas todo mundo espera isso.
Hans Passant
não se esqueça de marcar a resposta como aceita se tiver as informações que deseja ...
Pranay Rana
3
Você pode acessar variáveis ​​/ métodos estáticos por meio do tipo (neste caso Book) não por meio de uma instância ( book), então a solução mais fácil é Book.myInt.
Jaider

Respostas:

171

Uma staticvariável compartilha seu valor entre todas as instâncias da classe.

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

Explicação: Se você olhar o exemplo acima, eu apenas declaro a intvariável. Quando eu executar este código, a saída será 10e 10. É simples.

Agora, vamos examinar a variável estática aqui; Estou declarando a variável como um static.

Exemplo com variável 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();
    }
}

Agora, quando eu executar o código acima, a saída será 10e 15. Portanto, o valor da variável estática é compartilhado entre todas as instâncias dessa classe.

Kartik Patel
fonte
9
@Pranay: Sim, isso é melhor, mas se você me mostrar um exemplo que mostro acima, pode ser melhor para mim e para os outros ... de qualquer forma, bom esforço ...
Kartik Patel
1
É estático para a classe, ou seja, seu valor permanece fiel à classe com seu valor armazenado em seu ... aguarde ... classe
chwi
Você diz que uma variável estática é compartilhada entre todas as instâncias da classe ... mas e se não houver instâncias? Você ainda pode definir uma variável? É permitido armazenar dados dinâmicos em uma classe estática?
Kokodoko
@Kokodoko, mesmo se não houver instância, você certamente pode definir a variável. Isso define sua natureza estática
Ladmerc
33

C # não tem variáveis estáticas . Você pode declarar o campo estático na definição de tipo particular por meio de C #. O campo estático é um estado compartilhado com todas as instâncias de um tipo específico. Portanto, o escopo do campo estático é do tipo inteiro. É por isso que você não pode declarar um campo estático dentro de um método - o método é um escopo em si, e os itens declarados em um método devem ser inacessíveis além da borda do método.

Dennis
fonte
5
Bem, na documentação é declarado como "Um campo declarado com o modificador estático é chamado de variável estática." msdn.microsoft.com/en-us/library/aa691162(v=vs.71).aspx Mas você está certo no resto da explicação.
Teoman shipahi
19

variáveis ​​estáticas são usadas quando apenas uma cópia da variável é necessária. então, se você declarar a variável dentro do método, não há uso dela, ela se torna local para funcionar apenas ..

exemplo de estática é

class myclass
{
    public static int a = 0;
}

Variáveis ​​declaradas como estáticas são comumente compartilhadas por todas as instâncias de uma classe.

Variáveis ​​declaradas como estáticas são comumente compartilhadas por todas as instâncias de uma classe. Quando você cria várias instâncias da classe VariableTest, essa variável permanente é compartilhada por todas elas. Portanto, em qualquer ponto do tempo, haverá apenas um valor de string contido na variável permanente.

Como há apenas uma cópia da variável disponível para todas as instâncias, o código this.permament resultará em erros de compilação porque pode ser lembrado que this.variablename se refere ao nome da variável de instância. Assim, as variáveis ​​estáticas devem ser acessadas diretamente, conforme indicado no código.

Pranay Rana
fonte
você pode explicar com um exemplo?
Kartik Patel
mas se eu fizer a instância de uma classe, então não poderei acessar a variável estática. por que? Posso acessar a variável estática por classname.variable, mas não tornando a instância de uma classe .......... ......
Kartik Patel
@Kartik Patel porque você tem que usar o nome da classe para acessar o myInt estático. Por que é assim, não sei. Mas eu diria que é muito mais claro porque você deseja acessar uma parte estática da classe, não é estática se você precisar de uma instância para acessá-la.
agora para
@dowhilefor: Mas como você mencionou acima, "Variáveis ​​declaradas estáticas são comumente compartilhadas em todas as instâncias de uma classe." então qual é o significado disso?
Kartik Patel
@Kartik Patel você não pode acessar a variável de fora com uma instância, mas você sempre pode usar a variável estática dentro de sua classe e então ela é compartilhada entre todas as instâncias. Também não fui eu quem deu esta resposta, estou apenas a comentar.
agora para
9

Alguns exemplos do "mundo real" para variáveis ​​estáticas:

construir uma classe onde você pode alcançar valores codificados para seu aplicativo. Semelhante a uma enumeração, mas com mais flexibilidade no tipo de dados.

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

O singleton amplamente conhecido, permite controlar para ter exatamente uma instância de uma classe. Isso é muito útil se você quiser acessá-lo em todo o seu aplicativo, mas não passá-lo para todas as classes apenas para permitir que essa classe o 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; }
        }
    }

e é assim que você chamaria o gerenciador de textura

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

Sobre sua última pergunta: você está se referindo ao erro do compilador CS0176 . Tentei encontrar mais informações sobre isso, mas só consegui descobrir o que o msdn tinha a dizer sobre isso:

Um método, campo, propriedade ou evento estático pode ser chamado em uma classe, mesmo quando nenhuma instância da classe foi criada. Se alguma instância da classe for criada, ela não poderá ser usada para acessar o membro estático. Existe apenas uma cópia de campos e eventos estáticos, e os métodos e propriedades estáticos só podem acessar campos e eventos estáticos.

por enquanto
fonte
5

Variáveis ​​estáticas são usadas quando apenas uma cópia delas é necessária. Deixe-me explicar isso com um exemplo:

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

Agora aqui nós criamos 2 instâncias para nosso classcírculo, ou seja, 2 conjuntos de cópias _PI juntamente com outras variáveis ​​são criados. Portanto, digamos que se tivermos muitas instâncias dessa classe, várias cópias de _PIserão criadas ocupando a memória. Então, nesses casos, é melhor fazer com que essas variáveis ​​se pareçam _PI statice operem com elas.

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

Agora, não importa quantas instâncias são feitas para o classcírculo, existe apenas uma cópia da variável _PIsalvando nossa memória.

TomHardy
fonte
4

Classes estáticas não exigem que você crie um objeto dessa classe / instancie-as, você pode prefixar a palavra-chave C # estática na frente do nome da classe, para torná-la estática.

Lembre-se: não estamos instanciando a classe Console, classe String, classe 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
fonte
observação muito boa porque se você tentar usar object para acessar o valor da propriedade myInt the você obterá um erro: static void Main () {Book book = new Book (); // isso dá um erro: book.myInt = 5;
leonidaa

2

Começando com este exemplo do @Kartik Patel, eu mudei um pouco, talvez agora esteja mais claro sobre a variável 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. Variável de classe VS Variável de instância em C #

    Membros da classe estática C # OU Variável de classe

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

    }

insira a descrição da imagem aqui insira a descrição da imagem aqui insira a descrição da imagem aqui insira a descrição da imagem aqui

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
exatamente, veja o exemplo acima de @Kunal Mukherjee
leonidaa
1

Os membros de dados e membros de função que operam na instância do tipo são chamados de membros de instância. O método ToString de int (por exemplo) são exemplos de membros de instância. Por padrão, os membros são membros da instância. Membros de dados e membros de função que não operam na instância do tipo, mas sim no próprio tipo, devem ser marcados como estáticos. Os métodos Test.Main e Console.WriteLine são métodos estáticos. A classe Console é, na verdade, uma classe estática, o que significa que todos os seus membros são estáticos. Você nunca realmente cria instâncias de um console - um console é compartilhado por todo o aplicativo.

Michael Y
fonte
1

Em resposta ao "quando usar?" questão:

Costumo usar uma variável estática (classe) para atribuir um ID de instância exclusivo a cada instância de uma classe. Eu uso o mesmo código em todas as aulas, é muito simples:

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

Isso ilustra alguns pontos sobre variáveis ​​e métodos estáticos:

  1. Variáveis ​​e métodos estáticos são associados à classe, não a qualquer instância específica da classe.
  2. Um método estático pode ser chamado no construtor de uma instância - neste caso, o método estático NextIID é usado para inicializar a propriedade somente leitura IID, que é o ID exclusivo para esta instância.

Acho isso útil porque desenvolvo aplicativos nos quais enxames de objetos são usados ​​e é bom ser capaz de rastrear quantos foram criados e rastrear / consultar instâncias individuais.

Eu também uso variáveis ​​de classe para rastrear coisas como totais e médias de propriedades das instâncias que podem ser relatadas em tempo real. Acho que a classe é um bom lugar para manter informações resumidas sobre todas as instâncias da classe.

JohnRC
fonte
0

Tente ligar diretamente com o nome da classe Book.myInt

Arnold Parge
fonte
exatamente, veja o exemplo acima de @Kunal Mukherjee
leonidaa
0

Em comparação com as variáveis ​​de sessão, as variáveis ​​estáticas terão o mesmo valor para todos os usuários, considerando que estou usando um aplicativo que é implantado no servidor. Se dois usuários acessarem a mesma página de um aplicativo, a variável estática manterá o valor mais recente e o mesmo valor será fornecido a ambos os usuários, ao contrário das variáveis ​​de sessão que são diferentes para cada usuário. Portanto, se você quiser algo comum e igual para todos os usuários, incluindo os valores que devem ser usados ​​ao longo do código do aplicativo, use apenas estático.

pratham gn
fonte
0

Você não precisa instanciar um objeto, porque você vai usar uma variável estática: Console.WriteLine (Book.myInt);

Mehran Sarrafi
fonte
-1

A variável estática retém seu valor anterior até a saída do programa. Static é usado chamando diretamente class_Name.Method () ou class_Name.Property. Nenhuma referência de objeto é necessária. O uso mais popular de estática é a classe matemática do C #. Math.Sin (), Math.Cos (), Math.Sqrt ().

Md Shahriar
fonte