C#: Membros estáticos e métodos de extensão

1. Campos e métodos estáticos

Os membros de static pertencem ao próprio tipo, e não a nenhuma instância. Todas as instâncias compartilham o mesmo campo estático. Os métodos estáticos são chamados por meio de ClassName.Member sem a criação de um objeto.

▶ Exemplo

CSHARP
class Counter
{
    public static int TotalCount = 0;
    public int InstanceId;

    public Counter(int id)
    {
        InstanceId = id;
        TotalCount++;
    }

    public static void Report()
    {
        Console.WriteLine($"{TotalCount} instances created");
    }
}

Counter a = new Counter(1);
Counter b = new Counter(2);
Counter.Report();
Console.WriteLine(Counter.TotalCount);
▶ Experimente
TEXT 📖 Somente leitura
2 instances created
2
💡 Os métodos static não podem usar this e não podem acessar diretamente os membros da instância — eles só podem acessar outros membros estáticos.


2. Construtores estáticos

Um construtor estático é executado automaticamente uma única vez, no primeiro acesso à classe, e apenas uma vez. Ele não pode conter modificadores de acesso nem parâmetros, e é comumente usado para inicializar campos estáticos.

▶ Exemplo

CSHARP
class Config
{
    public static readonly DateTime StartTime;

    static Config()
    {
        StartTime = DateTime.Now;
        Console.WriteLine("Static constructor executed");
    }
}

Console.WriteLine("Preparing to access Config");
Console.WriteLine(Config.StartTime);
Console.WriteLine(Config.StartTime);
▶ Experimente
TEXT 📖 Somente leitura
Preparing to access Config
Static constructor executed
2026/06/28 10:00:00
2026/06/28 10:00:00
⚠️ Um construtor estático é acionado apenas uma vez — acessar os membros estáticos da classe várias vezes não fará com que ele seja executado novamente.


3. Classes estáticas (Padrão de Classe de Utilidade)

Uma classe declarada com static class não pode ser instanciada nem herdada. Todos os membros devem ser estáticos, o que a torna adequada para encapsular métodos utilitários.

▶ Exemplo

CSHARP
static class MathHelper
{
    public static double Square(double x) => x * x;
    public static double Hypotenuse(double a, double b) => Math.Sqrt(Square(a) + Square(b));
}

Console.WriteLine(MathHelper.Square(3));
Console.WriteLine(MathHelper.Hypotenuse(3, 4));
▶ Experimente
TEXT 📖 Somente leitura
9
5
📌 Ao tentar new MathHelper(), ocorre um erro de compilação — classes estáticas não podem ser instanciadas.


4. const x static readonly

Matéria const static readonly
Quando atribuído Tempo de compilação Tempo de execução
Tipos de valor Apenas tipos embutidos Qualquer tipo
Mutável Imutável Imutável após atribuição no construtor

▶ Exemplo

CSHARP
class Settings
{
    public const int MaxRetry = 3;
    public static readonly DateTime LaunchTime;

    static Settings()
    {
        LaunchTime = DateTime.Now;
    }
}

Console.WriteLine(Settings.MaxRetry);
Console.WriteLine(Settings.LaunchTime);
▶ Experimente
TEXT 📖 Somente leitura
3
2026/06/28 10:00:00
⚠️ Os valores const são incorporados ao assembly do chamador em tempo de compilação. Se uma constante for modificada, todos os assemblies que fazem referência a ela devem ser recompilados. static readonly é lido em tempo de execução, o que o torna mais seguro.


5. Métodos de extensão

Os métodos de extensão “adicionam” métodos a um tipo existente sem modificá-lo. Eles são definidos em uma classe estática, e o primeiro parâmetro é precedido pela palavra-chave this, o que permite que sejam chamados como se fossem métodos de instância.

▶ Exemplo

CSHARP
static class StringExt
{
    public static bool IsEmpty(this string s) => s.Length == 0;
    public static string Repeat(this string s, int count)
    {
        var sb = new StringBuilder();
        for (int i = 0; i < count; i++) sb.Append(s);
        return sb.ToString();
    }
}

Console.WriteLine("hello".IsEmpty());
Console.WriteLine("ab".Repeat(3));
▶ Experimente
TEXT 📖 Somente leitura
False
ababab
💡 Os métodos de extensão são, essencialmente, chamadas de métodos estáticos — o compilador traduz s.IsEmpty() em StringExt.IsEmpty(s). Os métodos de instância têm precedência sobre os métodos de extensão.


6. Métodos de extensão na prática (Fundamentos do LINQ)

A sintaxe fluente do LINQ é baseada em métodos de extensão. Where, Select, OrderBy e outros em System.Linq.Enumerable são todos métodos de extensão de IEnumerable<T>.

▶ Exemplo

CSHARP
static class EnumerableExt
{
    public static IEnumerable```<T>``` MyWhere```<T>```(this IEnumerable```<T>``` source, Func`<T, bool>` predicate)
    {
        foreach (var item in source)
        {
            if (predicate(item)) yield return item;
        }
    }
}

int[] nums = { 1, 2, 3, 4, 5, 6 };
var even = nums.MyWhere(n => n % 2 == 0);
Console.WriteLine(string.Join(", ", even));
▶ Experimente
TEXT 📖 Somente leitura
2, 4, 6
🚀 Depois que você entender como funcionam os métodos de extensão, ler o código-fonte do LINQ se torna algo simples — trata-se, na verdade, de uma coleção bem projetada de métodos de extensão.


7. Classes parciais

A palavra-chave partial permite que a definição de uma classe seja dividida em vários arquivos, os quais são mesclados em uma única classe completa no momento da compilação. Isso é comumente usado para separar o código gerado automaticamente do código escrito manualmente.

▶ Exemplo

CSHARP
partial class User
{
    public string Name { get; set; }
    public User(string name) => Name = name;
}

partial class User
{
    public void Greet() => Console.WriteLine($"Hello, {Name}");
}

var u = new User("Alice");
u.Greet();
▶ Experimente
TEXT 📖 Somente leitura
Hello, Alice
📌 Frameworks como WinForms, WPF e EF Core utilizam amplamente classes parciais para separar o código gerado pelo designer da lógica de negócios.


8. Métodos parciais

Um método parcial é declarado em uma parte de uma classe parcial e, opcionalmente, implementado em outra parte. Se não for implementado, o compilador remove o local da chamada — sem sobrecarga. A partir do C# 9, os métodos parciais não têm mais restrições de assinatura.

▶ Exemplo

CSHARP
partial class Order
{
    public int Amount { get; set; }
    partial void OnCreated();

    public Order(int amount)
    {
        Amount = amount;
        OnCreated();
    }
}

partial class Order
{
    partial void OnCreated() => Console.WriteLine("Order created");
}

var o = new Order(100);
Console.WriteLine(o.Amount);
▶ Experimente
TEXT 📖 Somente leitura
Order created
100
💡 Se você remover a implementação OnCreated da segunda classe parcial, o programa ainda compila, e o local da chamada é automaticamente removido pelo compilador.

❓ Perguntas Frequentes

P: Os métodos estáticos podem acessar campos de instância? R: Não. Os métodos estáticos não estão associados a nenhuma instância — é preciso usar uma referência a um objeto para acessar membros de instância.

P: Devo usar const ou static readonly? R: Use const para constantes simples conhecidas em tempo de compilação; use static readonly para valores determinados em tempo de execução ou para tipos de referência.

P: Os métodos de extensão podem acessar membros privados? R: Não. Os métodos de extensão são, essencialmente, métodos estáticos e só podem acessar membros públicos.

P: Todas as partes de uma classe parcial devem estar no mesmo assembly? R: Sim, todas as partes de uma classe parcial devem estar no mesmo assembly e no mesmo namespace.

📖 Resumo

📝 Exercícios

  1. Escreva um static class ArrayHelper com os métodos estáticos Max(int[] arr) e Average(int[] arr) e teste-os no Main
  2. Escreva um método de extensão MySum para IEnumerable<int> que calcule a soma de uma sequência de números inteiros sem usar LINQ
  3. Crie um partial class Logger — em uma parte, declare partial void OnLog(string message) e um método Log(string msg) (que chama OnLog internamente); na outra parte, implemente OnLog para gravar no console
  4. Defina um campo const e um campo static readonly e escreva um código para verificar se const é substituído em tempo de compilação, enquanto static readonly é lido em tempo de execução (dica: faça referência a eles a partir de outro assembly e observe o comportamento após a modificação)
Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%