Classes estáticas e membros de classes estáticas (Guia de programação em C#)

Uma classe estática é basicamente o mesmo que uma classe não estática, mas há uma diferença: uma classe estática não pode ser instanciada. Em outras palavras, você não pode usar o novo operador para criar uma variável do tipo de classe. Como não há nenhuma variável de instância, você acessa os membros de uma classe estática usando o próprio nome da classe. Por exemplo, se você tiver uma classe estática nomeada UtilityClass que tenha um método estático público chamado MethodA, chame o método conforme mostrado no exemplo a seguir:

UtilityClass.MethodA();  

Uma classe estática pode ser usada como um contêiner conveniente para conjuntos de métodos que operam apenas em parâmetros de entrada e não precisam obter ou definir campos de instância interna. Por exemplo, na biblioteca de classes .NET, a classe estática System.Math contém métodos que executam operações matemáticas, sem qualquer requisito para armazenar ou recuperar dados que são exclusivos para uma instância específica da Math classe. Ou seja, você aplica os membros da classe especificando o nome da classe e o nome do método, conforme mostrado no exemplo a seguir.

double dub = -3.14;  
Console.WriteLine(Math.Abs(dub));  
Console.WriteLine(Math.Floor(dub));  
Console.WriteLine(Math.Round(Math.Abs(dub)));  
  
// Output:  
// 3.14  
// -4  
// 3  

Como é o caso com todos os tipos de classe, o tempo de execução do .NET carrega as informações de tipo para uma classe estática quando o programa que faz referência à classe é carregado. O programa não pode especificar exatamente quando a classe é carregada. No entanto, é garantido carregar e ter seus campos inicializados e seu construtor estático chamado antes que a classe seja referenciada pela primeira vez em seu programa. Um construtor estático é chamado apenas uma vez, e uma classe estática permanece na memória durante o tempo de vida do domínio do aplicativo no qual o programa reside.

Nota

Para criar uma classe não estática que permita que apenas uma instância de si mesma seja criada, consulte Implementando Singleton em C#.

A lista a seguir fornece os principais recursos de uma classe estática:

  • Contém apenas membros estáticos.

  • Não é possível instanciar.

  • Está selado.

  • Não é possível conter construtores de instância.

Criar uma classe estática é, portanto, basicamente o mesmo que criar uma classe que contém apenas membros estáticos e um construtor privado. Um construtor privado impede que a classe seja instanciada. A vantagem de usar uma classe estática é que o compilador pode verificar se nenhum membro da instância é adicionado acidentalmente. O compilador garante que instâncias dessa classe não podem ser criadas.

As classes estáticas são seladas e, portanto, não podem ser herdadas. Eles não podem herdar de nenhuma classe ou interface, exceto Object. As classes estáticas não podem conter um construtor de instância. No entanto, eles podem conter um construtor estático. As classes não estáticas também devem definir um construtor estático se a classe contiver membros estáticos que exijam inicialização não trivial. Para obter mais informações, consulte Construtores estáticos.

Exemplo

Aqui está um exemplo de uma classe estática que contém dois métodos que convertem a temperatura de Celsius para Fahrenheit e de Fahrenheit para Celsius:

public static class TemperatureConverter
{
    public static double CelsiusToFahrenheit(string temperatureCelsius)
    {
        // Convert argument to double for calculations.
        double celsius = Double.Parse(temperatureCelsius);

        // Convert Celsius to Fahrenheit.
        double fahrenheit = (celsius * 9 / 5) + 32;

        return fahrenheit;
    }

    public static double FahrenheitToCelsius(string temperatureFahrenheit)
    {
        // Convert argument to double for calculations.
        double fahrenheit = Double.Parse(temperatureFahrenheit);

        // Convert Fahrenheit to Celsius.
        double celsius = (fahrenheit - 32) * 5 / 9;

        return celsius;
    }
}

class TestTemperatureConverter
{
    static void Main()
    {
        Console.WriteLine("Please select the convertor direction");
        Console.WriteLine("1. From Celsius to Fahrenheit.");
        Console.WriteLine("2. From Fahrenheit to Celsius.");
        Console.Write(":");

        string? selection = Console.ReadLine();
        double F, C = 0;

        switch (selection)
        {
            case "1":
                Console.Write("Please enter the Celsius temperature: ");
                F = TemperatureConverter.CelsiusToFahrenheit(Console.ReadLine() ?? "0");
                Console.WriteLine("Temperature in Fahrenheit: {0:F2}", F);
                break;

            case "2":
                Console.Write("Please enter the Fahrenheit temperature: ");
                C = TemperatureConverter.FahrenheitToCelsius(Console.ReadLine() ?? "0");
                Console.WriteLine("Temperature in Celsius: {0:F2}", C);
                break;

            default:
                Console.WriteLine("Please select a convertor.");
                break;
        }

        // Keep the console window open in debug mode.
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }
}
/* Example Output:
    Please select the convertor direction
    1. From Celsius to Fahrenheit.
    2. From Fahrenheit to Celsius.
    :2
    Please enter the Fahrenheit temperature: 20
    Temperature in Celsius: -6.67
    Press any key to exit.
 */

Membros estáticos

Uma classe não estática pode conter métodos, campos, propriedades ou eventos estáticos. O membro estático é chamável em uma classe, mesmo quando nenhuma instância da classe existe. O membro estático é sempre acessado pelo nome da classe, não pelo nome da instância. Existe apenas uma cópia de um membro estático, independentemente de quantas instâncias da classe são criadas. Os métodos e propriedades estáticos não podem acessar campos e eventos não estáticos em seu tipo de contenção, e eles não podem acessar uma variável de instância de qualquer objeto, a menos que ela seja explicitamente passada em um parâmetro de método.

É mais comum declarar uma classe não estática com alguns membros estáticos do que declarar uma classe inteira como estática. Dois usos comuns de campos estáticos são manter uma contagem do número de objetos que são instanciados ou armazenar um valor que deve ser compartilhado entre todas as instâncias.

Os métodos estáticos podem ser sobrecarregados, mas não substituídos, porque pertencem à classe e não a qualquer instância da classe.

Embora um campo não possa ser declarado como static const, um campo const é essencialmente estático em seu comportamento. Pertence ao tipo, não a instâncias do tipo. Portanto, const os campos podem ser acessados usando a mesma ClassName.MemberName notação usada para campos estáticos. Nenhuma instância de objeto é necessária.

C# não suporta variáveis locais estáticas (ou seja, variáveis que são declaradas no escopo do método).

Você declara membros de classe estática usando a static palavra-chave antes do tipo de retorno do membro, conforme mostrado no exemplo a seguir:

public class Automobile
{
    public static int NumberOfWheels = 4;

    public static int SizeOfGasTank
    {
        get
        {
            return 15;
        }
    }

    public static void Drive() { }

    public static event EventType? RunOutOfGas;

    // Other non-static fields and properties...
}

Os membros estáticos são inicializados antes que o membro estático seja acessado pela primeira vez e antes que o construtor estático, se houver, seja chamado. Para acessar um membro de classe estática, use o nome da classe em vez de um nome de variável para especificar o local do membro, conforme mostrado no exemplo a seguir:

Automobile.Drive();
int i = Automobile.NumberOfWheels;

Se sua classe contiver campos estáticos, forneça um construtor estático que os inicialize quando a classe for carregada.

Uma chamada para um método estático gera uma instrução de chamada em linguagem intermediária da Microsoft (MSIL), enquanto uma chamada para um método de instância gera uma callvirt instrução, que também verifica se há referências de objeto nulas. No entanto, na maioria das vezes, a diferença de desempenho entre os dois não é significativa.

Especificação da linguagem C#

Para obter mais informações, consulte Classes estáticas, Membros estáticos e de instância e Construtores estáticos na Especificação da linguagem C#. A especificação da linguagem é a fonte definitiva para a sintaxe e o uso do C#.

Consulte também