0Pricing
C# Academy · Aula

Matemática genérica (visão geral), atributos genéricos (quando relevante)

Emule matemática genérica sem recursos modernos: passe um provedor de operações ou delegados, restrinja os tipos cuidadosamente e simule "atributos genéricos" por meio de parâmetros Type.

Matemática genérica (visão geral), atributos genéricos (quando relevante) é uma aula grátis de C# Academy no CoddyKit. Esta é a aula 2 de 3. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de C# Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de C# Academy inclui 3 aulas no total.

Matemática genérica no C# 6

Objetivo: escrever algoritmos numéricos genéricos no C# 6.

  • Não há operadores estáticos abstratos em T
  • Soluções alternativas: interface fornecedora de operações ou pequenos delegados
  • Para anotações, use atributos com parâmetros Type

Padrão de fornecimento de operações

Forneça o valor zero e Add por meio de uma interface. O algoritmo genérico chama esses métodos em vez de usar o operador + em T.

using System;
using System.Collections.Generic;

public interface INumericOps<T>
{
  T Zero { get; }
  T Add(T a, T b);
}

public sealed class IntOps : INumericOps<int>
{
  public int Zero { get { return 0; } }
  public int Add(int a, int b) { return a + b; }
}

public sealed class DoubleOps : INumericOps<double>
{
  public double Zero { get { return 0.0; } }
  public double Add(double a, double b) { return a + b; }
}

public class Program
{
  static T Sum<T>(IEnumerable<T> items, INumericOps<T> ops)
  {
    T acc = ops.Zero;
    foreach (T x in items) acc = ops.Add(acc, x);
    return acc;
  }

  public static void Main(string[] args)
  {
    int s1 = Sum(new int[] {1,2,3}, new IntOps());
    double s2 = Sum(new double[] {1.5, 2.0}, new DoubleOps());
    Console.WriteLine("Sum int = " + s1);
    Console.WriteLine("Sum double = " + s2);
  }
}

Média com auxiliares

Para operações que não podem ser expressas genericamente, como a divisão, passe um pequeno conversor ou um delegado adicional.

using System;
using System.Collections.Generic;

public interface INumericOps<T>
{
  T Zero { get; }
  T Add(T a, T b);
}

public sealed class DoubleOps : INumericOps<double>
{
  public double Zero { get { return 0.0; } }
  public double Add(double a, double b) { return a + b; }
}

public class Program
{
  static double Average<T>(IEnumerable<T> items, INumericOps<T> ops, Func<T,double> toDouble)
  {
    T acc = ops.Zero;
    int count = 0;
    foreach (T x in items) { acc = ops.Add(acc, x); count++; }
    if (count == 0) throw new ArgumentException("Empty sequence", "items");
    // convert with a delegate for division
    return toDouble(acc) / count;
  }

  public static void Main(string[] args)
  {
    double avg = Average<double>(new double[] {2.0, 4.0, 6.0}, new DoubleOps(), delegate(double d) { return d; });
    Console.WriteLine("Avg = " + avg);
  }
}

Redução baseada em delegado

Os delegados mantêm a solução mínima: passe um valor inicial e uma função de combinação. Isso é adequado para pequenos utilitários.

using System;

public class Program
{
  static T Fold<T>(T[] xs, T seed, Func<T,T,T> combine)
  {
    T acc = seed;
    for (int i = 0; i < xs.Length; i++) acc = combine(acc, xs[i]);
    return acc;
  }

  public static void Main(string[] args)
  {
    int sum = Fold<int>(new int[] {1,2,3}, 0, delegate(int a, int b) { return a + b; });
    double sumD = Fold<double>(new double[] {1.5, 2.5}, 0.0, delegate(double a, double b) { return a + b; });
    Console.WriteLine("Sum ints = " + sum);
    Console.WriteLine("Sum doubles = " + sumD);
  }
}

Alternativa para atributos

Não há atributos genéricos verdadeiros no C# 6. Passe um Type ao atributo para indicar o tipo genérico relacionado.

using System;
using System.Reflection;

// C# 6 cannot declare generic attributes. Workaround: pass a Type.
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public sealed class ValidatorForAttribute : Attribute
{
  public Type TargetType { get; private set; }
  public ValidatorForAttribute(Type targetType) { TargetType = targetType; }
}

public sealed class Customer { public string Name; }

[ValidatorFor(typeof(Customer))]
public sealed class CustomerValidator
{
  public bool IsValid(Customer c) { return c != null && !string.IsNullOrEmpty(c.Name); }
}

public class Program
{
  public static void Main(string[] args)
  {
    Type t = typeof(CustomerValidator);
    object[] attrs = t.GetCustomAttributes(typeof(ValidatorForAttribute), false);
    if (attrs.Length > 0)
    {
      ValidatorForAttribute a = (ValidatorForAttribute)attrs[0];
      Console.WriteLine("Validator targets: " + a.TargetType.Name);
    }
  }
}

Dicas e escolhas

Dicas:

  • Prefira um fornecedor de operações para algoritmos numéricos reutilizáveis.
  • Use delegados para pequenos auxiliares, como combinar e converter.
  • Para anotações, passe Type nos atributos e leia-o por reflexão.

Alternativa para matemática genérica

Verificação rápida: no C# 6, qual é uma maneira prática de escrever uma função genérica de soma sem matemática genérica moderna?

Recapitulação

Recapitulação: sem matemática genérica moderna, passe operações ou delegados aos seus algoritmos. Para anotações, use atributos que carreguem um Type e leia-o por reflexão.

Perguntas Frequentes

A aula “Matemática genérica (visão geral), atributos genéricos (quando relevante)” é grátis?

Sim — o texto completo de “Matemática genérica (visão geral), atributos genéricos (quando relevante)” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de C# Academy, atualize para CoddyKit PRO. O curso de C# Academy inclui 3 aulas no total.

O que vou aprender em “Matemática genérica (visão geral), atributos genéricos (quando relevante)”?

Emule matemática genérica sem recursos modernos: passe um provedor de operações ou delegados, restrinja os tipos cuidadosamente e simule "atributos genéricos" por meio de parâmetros Type. Você pratica C# Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar C# Academy?

Nenhuma experiência prévia é necessária. C# Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 3.

Quanto tempo leva a aula “Matemática genérica (visão geral), atributos genéricos (quando relevante)”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de C# Academy?

Sim. Cada aula de C# Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. unmanaged, notnull, new() (emulação no C# 6)
  2. Matemática genérica (visão geral), atributos genéricos (quando relevante)
  3. Utilitários genéricos reutilizáveis
← Voltar para C# Academy