0Pricing
C# Academy · Lezione

Matematica generica (panoramica), attributi generici (quando pertinenti)

Emulate la matematica generica senza funzionalità moderne: passate un provider di operazioni o dei delegate, applicate con attenzione i vincoli sui tipi e simulate i «generic attributes» tramite parametri Type.

Matematica generica (panoramica), attributi generici (quando pertinenti) è una lezione C# Academy gratuita su CoddyKit. Questa è la lezione 2 di 3. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento C# Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso C# Academy include 3 lezioni in totale.

Calcolo generico in C# 6

Obiettivo: scrivere algoritmi numerici generici in C# 6.

  • Nessun operatore statico astratto su T
  • Soluzioni alternative: interfaccia ops-provider o piccoli delegati
  • Per le annotazioni, utilizzi attributi con parametri Type

Pattern ops-provider

Fornisca Zero e Add tramite un'interfaccia. L'algoritmo generico chiama questi metodi invece di utilizzare + su 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);
  }
}

Media con helper

Per le operazioni che non è possibile esprimere in modo generico (come la divisione), passi un piccolo convertitore o un delegato aggiuntivo.

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 basato su delegato

I delegati mantengono il codice essenziale: passi un valore iniziale e una funzione di combinazione. È una soluzione adatta ai piccoli strumenti.

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);
  }
}

Soluzione alternativa con attributi

In C# 6 non esistono veri attributi generici. Passi un Type all'attributo per indicare il tipo generico correlato.

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);
    }
  }
}

Suggerimenti e scelte

Suggerimenti:

  • Preferisca un ops-provider per gli algoritmi numerici riutilizzabili.
  • Utilizzi i delegati per i piccoli helper (combinazione, conversione).
  • Per le annotazioni, passi Type negli attributi e lo legga tramite reflection.

Soluzione alternativa per il calcolo generico

Verifica rapida: in C# 6, qual è un modo pratico per scrivere un Sum generico senza il calcolo generico moderno?

Riepilogo

Riepilogo: in assenza del calcolo generico moderno, passi ops o delegati agli algoritmi. Per le annotazioni, utilizzi attributi che contengono un Type e lo legga tramite reflection.

Domande Frequenti

La lezione «Matematica generica (panoramica), attributi generici (quando pertinenti)» è gratuita?

Sì — il testo completo di «Matematica generica (panoramica), attributi generici (quando pertinenti)» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso C# Academy, passa a CoddyKit PRO. Il corso C# Academy include 3 lezioni in totale.

Cosa imparerò in «Matematica generica (panoramica), attributi generici (quando pertinenti)»?

Emulate la matematica generica senza funzionalità moderne: passate un provider di operazioni o dei delegate, applicate con attenzione i vincoli sui tipi e simulate i «generic attributes» tramite para… Eserciti C# Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare C# Academy?

Non è richiesta alcuna esperienza precedente. C# Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 3.

Quanto tempo richiede la lezione «Matematica generica (panoramica), attributi generici (quando pertinenti)»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione C# Academy?

Sì. Ogni lezione C# Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. unmanaged, notnull, new() (emulazione in C# 6)
  2. Matematica generica (panoramica), attributi generici (quando pertinenti)
  3. Utility generiche riutilizzabili
← Torna a C# Academy