0Pricing
C# Academy · Lección

Matemática genérica (visión general) y atributos genéricos (cuando corresponda)

Emule la matemática genérica sin funcionalidades modernas: transmita un proveedor de operaciones o delegates, restrinja los tipos cuidadosamente y simule los «atributos genéricos» mediante parámetros Type.

Matemática genérica (visión general) y atributos genéricos (cuando corresponda) es una lección gratuita de C# Academy en CoddyKit. Esta es la lección 2 de 3. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de C# Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de C# Academy incluye 3 lecciones en total.

Matemáticas genéricas en C# 6

Objetivo: Escriba algoritmos numéricos genéricos en C# 6.

  • No hay operadores abstractos estáticos sobre T
  • Alternativas: una interfaz ops-provider o pequeños delegates
  • Para las anotaciones, use atributos con parámetros Type

Patrón ops-provider

Proporcione Zero y Add mediante una interfaz. El algoritmo genérico llama a esos métodos en lugar de utilizar + sobre 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);
  }
}

Promedio con auxiliares

Para las operaciones que no puede expresar de forma genérica (como la división), pase un pequeño converter o un delegate 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);
  }
}

Fold basado en delegates

Los delegates mantienen el código mínimo: pase un valor inicial y una función de combinación. Es una buena opción para utilidades pequeñas.

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

C# 6 no admite verdaderos atributos genéricos. Pase un Type al atributo para indicar el 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);
    }
  }
}

Consejos y opciones

Consejos:

  • Prefiera un ops-provider para algoritmos numéricos reutilizables.
  • Use delegates para auxiliares pequeños (combinar, convertir).
  • Para las anotaciones, pase Type en los atributos y léalo mediante reflection.

Alternativa para matemáticas genéricas

Comprobación rápida: En C# 6, ¿cuál es una forma práctica de escribir un Sum genérico sin las matemáticas genéricas modernas?

Repaso

Repaso: Sin las matemáticas genéricas modernas, pase ops o delegates a sus algoritmos. Para las anotaciones, use atributos que contengan un Type y léalo mediante reflection.

Preguntas frecuentes

¿La lección «Matemática genérica (visión general) y atributos genéricos (cuando corresponda)» es gratis?

Sí — el texto completo de «Matemática genérica (visión general) y atributos genéricos (cuando corresponda)» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de C# Academy, actualiza a CoddyKit PRO. El curso de C# Academy incluye 3 lecciones en total.

¿Qué aprenderé en «Matemática genérica (visión general) y atributos genéricos (cuando corresponda)»?

Emule la matemática genérica sin funcionalidades modernas: transmita un proveedor de operaciones o delegates, restrinja los tipos cuidadosamente y simule los «atributos genéricos» mediante parámetros… Practicas C# Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar C# Academy?

No se requiere experiencia previa. C# Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 2 de 3.

¿Cuánto tiempo toma la lección «Matemática genérica (visión general) y atributos genéricos (cuando corresponda)»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de C# Academy?

Sí. Cada lección de C# Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. unmanaged, notnull y new() (emulación de C# 6)
  2. Matemática genérica (visión general) y atributos genéricos (cuando corresponda)
  3. Utilidades genéricas reutilizables
← Volver a C# Academy