Médio C#

Permissões com Flags

Enunciado

Defina um enum [Flags] Permissao com os valores Nenhuma = 0, Ler = 1, Escrever = 2, Executar = 4. Crie um método que recebe uma combinação de permissões e imprime quais estão ativas. No Main, teste com Ler | Executar e depois remova Executar usando XOR (^).

Requisitos

  • Use o atributo [Flags] e valores que sejam potências de 2.
  • Implemente um método ImprimirPermissoes(Permissao p) que verifica cada flag com HasFlag.
  • No Main, combine Ler | Executar, imprima, depois faça p ^= Permissao.Executar e imprima novamente.
  • A saída deve listar as permissões ativas separadamente.

Código inicial

using System;

[Flags]
enum Permissao
{
    Nenhuma = 0,
    Ler = 1,
    Escrever = 2,
    Executar = 4
}

class Program
{
    static void ImprimirPermissoes(Permissao p)
    {
        // Implemente
    }

    static void Main()
    {
        // Teste as combinações
    }
}

Saída esperada

Permissões ativas: Ler, Executar
Permissões ativas: Ler
Ver dica

Use p.HasFlag(Permissao.Ler) para verificar cada flag. Para remover, use p ^= Permissao.Executar; que desliga o bit se estiver ligado.

Mostrar solução
using System;

[Flags]
enum Permissao
{
    Nenhuma = 0,
    Ler = 1,      // 0001
    Escrever = 2, // 0010
    Executar = 4  // 0100
}

class Program
{
    static void ImprimirPermissoes(Permissao p)
    {
        Console.Write("Permissões ativas: ");
        var ativas = new List<string>();

        if (p.HasFlag(Permissao.Ler)) ativas.Add("Ler");
        if (p.HasFlag(Permissao.Escrever)) ativas.Add("Escrever");
        if (p.HasFlag(Permissao.Executar)) ativas.Add("Executar");

        Console.WriteLine(string.Join(", ", ativas));
    }

    static void Main()
    {
        Permissao p = Permissao.Ler | Permissao.Executar; // combina com OR
        ImprimirPermissoes(p);

        p ^= Permissao.Executar; // remove Executar se estiver presente
        ImprimirPermissoes(p);
    }
}

Passo a passo

  1. Declaramos o enum com [Flags] e valores que são potências de 2 (1, 2, 4) para que cada bit represente uma permissão independente.
  2. O método ImprimirPermissoes cria uma lista de strings para armazenar os nomes das permissões ativas.
  3. Usamos p.HasFlag(Permissao.Ler) para testar se o bit correspondente está ligado; se sim, adicionamos o nome à lista.
  4. No Main, combinamos Ler e Executar com o operador | (OR bit a bit), resultando em 5 (0101).
  5. Chamamos ImprimirPermissoes e vemos "Ler, Executar".
  6. Depois, p ^= Permissao.Executar faz XOR com 4, desligando o bit de Executar (5 ^ 4 = 1).
  7. Imprimimos novamente e obtemos apenas "Ler".

Por que funciona

O atributo [Flags] indica que o enum pode ser tratado como um campo de bits. Cada valor é uma potência de 2, então a combinação com | ativa múltiplos bits. HasFlag verifica se um bit específico está ligado. O XOR (^) alterna o bit: se estiver ligado, desliga; se desligado, liga. Como usamos após ter certeza de que Executar estava ligado, ele é removido.

Erros comuns

  • Esquecer [Flags]: sem o atributo, a saída de ToString() pode não listar os nomes combinados corretamente, e a intenção não fica clara.
  • Valores não potência de 2: se usar Ler = 1, Escrever = 2, Executar = 3, o valor 3 combina bits de Ler e Escrever, causando sobreposição.
  • Usar & em vez de ^ para remover: p &= ~Permissao.Executar também funciona, mas ^ só remove se estiver presente; se não estiver, adiciona. No contexto, ^ é seguro porque sabemos que está presente.

Outra forma de resolver

Usar p &= ~Permissao.Executar; para remover de forma incondicional. É preferível quando você quer garantir que a permissão esteja desligada, independentemente do estado atual.

Saída esperada

Permissões ativas: Ler, Executar
Permissões ativas: Ler