A static
palavra-chave pode ser um pouco difícil de entender para iniciantes. Seu objetivo principal é identificar um membro da classe como não pertencente a nenhuma instância única da classe, mas à própria classe.
Sem entrar em muitos detalhes, o C # (e Java) impõe rigidamente o ideal orientado a objetos de que todo o código e dados devem pertencer a um objeto e, portanto, é limitado em escopo, visibilidade e tempo de vida. Geralmente, é uma prática recomendada sempre que o princípio fundamental de um objeto que representa alguma coisa do mundo real se aplica. No entanto, nem sempre; às vezes, o que você precisa é de uma função ou variável que você possa acessar de qualquer lugar no código, sem exigir que você passe uma referência a um objeto que o contenha e com a garantia de que os dados que você está vendo ou alterando sejam exatamente o que todos else está lidando com, e não uma cópia dele pertencente a uma instância diferente de um objeto.
Esse comportamento estava disponível em C e C ++ na forma da função ou variável "global", que não estava encapsulada em um objeto. Portanto, como compromisso, C # e Java suportam "escopo estático", um ponto intermediário entre código verdadeiramente global sem objeto pai e membros de instância de escopo limitado.
Qualquer "membro do código" (função, propriedade, campo) declarado como static
entra no escopo a partir da primeira linha da main()
função do programa e não o deixa até que a main()
função seja encerrada. Em inglês simples, um membro estático existe e pode ser usado enquanto o programa estiver em execução. Além disso, os membros estáticos são invocados chamando-os como membros do próprio tipo, não membros de nenhuma instância desse tipo:
public class Foo
{
public int MyInt {get;set;} //this is an "instance member"
public static int MyStaticInt {get;set;} //this is a "static member"
}
...
var myFoo = new Foo();
myFoo.MyInt = 5; //valid
myFoo.MyStaticInt = 5; //invalid; MyStaticInt doesn't belong to any one Foo
Foo.MyInt = 5; //invalid; MyInt only has meaning in the context of an instance
Foo.MyStaticInt = 2; //valid
Isso torna os membros estáticos visíveis para qualquer código que tenha conhecimento do tipo, sabendo ou não sobre uma única instância dele.
Para responder sua pergunta, o principal benefício de marcar algo como estático é que ele se torna visível onde quer que o próprio tipo seja conhecido, independentemente de o código consumidor ter ou poder obter uma instância do objeto que o contém. Há também um pequeno benefício de desempenho; como o método está no escopo estático, ele pode acessar apenas outros membros estáticos (da mesma classe ou de outros) e o que for passado como parâmetro. Portanto, o tempo de execução não precisa resolver nenhuma referência à instância atual do objeto que contém, como normalmente seria necessário para um método de instância para fornecer informações de estado específicas do contexto.
Classes inteiras também podem ser marcadas como estáticas; ao fazer isso, você informa ao compilador que a declaração de classe consistirá apenas em membros estáticos e, portanto, não poderá ser instanciada. Essa é uma maneira fácil de garantir que exista uma e apenas uma cópia de um objeto na memória; torne a classe e tudo nela estático. No entanto, é muito raro que esta seja a melhor solução para essa necessidade. Em uma situação em que exatamente uma cópia de um conjunto de dados é necessária, o "singleton" é normalmente recomendado; essa é uma classe não estática, que usa um acessador estático e um construtor não público para fornecer acesso a uma única instância. Teoricamente, um singleton oferece os mesmos benefícios de uma classe totalmente estática, mas com a capacidade adicional de usar a classe de uma maneira orientada a objeto e baseada em instância.