Generics con Where multipli: è possibile?

di il
3 risposte

Generics con Where multipli: è possibile?

Gentili,
sono di nuovo a richiedere un aiuto ai più esperti.
In pratica volevo implementare due metodi di estensione che effettuano l'arrotondamento per eccesso e difetto per n cifre, per i soli tipi double, decimal e float.

La prima implementazione è stata così:

public static class NumeriArrotondamento
{        
	public static T ArrotondaPerDifetto<T>(this T num, int numDecimali)
	{
		//codice che fa i calcoli
		return T // arrotondato per difetto              
	}
	
	public static T ArrotondaPerEccesso<T>(this T num, int numDecimali)
	{
		//codice che fa i calcoli
		return T // arrotondato per eccesso    
	}
}
Chiaramente con mio sommo disappunto, in questo modo tutti i tipi di oggetti si troveranno LOGICAMENTE ad avere questi metodi, il che non è il massimo; allora per limitare ho aggiunto una clausola Where del tipo:
public static T ArrotondaPerDifetto<T>(this T num, int numDecimali) where T: struct
per limitare ai soli tipi struct però anche tutti gli altri tipi struct si ritrovano con i metodi.

Ho provato allora a fare così:
public static T ArrotondaPerDifetto<T>(this T num, int numDecimali) where T: IComparable<Double>, IComparable<Decimal>, IComparable<Single>
però non funziona perché la virgola funziona in un certo senso come un AND.

Premesso che:
1) nei commenti Xml ai metodi ho specificato chiaramente che vanno usati solo ed esclusivamente per quei tre tipi;
2) i metodi ritornano un'eccezione per i tipi di dato non previsti con descrizione dell'errore molto esaustiva.

Secondo voi c'è un modo per implementare i due metodi alla perfezione, cioé c'è la possibilità del tipo Where : tipo1 OR tipo2 OR tipo3; oppure è meglio implementare i metodi separatamente per ciascun tipo senza ricorrere ai generics?

Ringrazio in anticipo chi vorrà darmi una dritta e vi saluto.

Lucius

3 Risposte

  • Re: Generics con Where multipli: è possibile?

    Non penso che si possa fare.

    Perché non vuoi usare le 3 estensioni separatamente ?
    (ho scritto 3 perchè potresti aggiungere un valore di tipo Bool per indicare se si tratta di un arrotondamento per eccesso o per difetto)

    Se vuoi ottimizzare il codice per non essere ripetitivo, puoi poggiarti su una funzione locale e passare i 3 valori come un unico parametro di tipo ValueType, da cui tutti e 3 derivano.

    Alla fine ti bastano 3 Estensioni ed una Funzione.
  • Re: Generics con Where multipli: è possibile?

    Visto che si ha a che fare solo con tipi decimal, double e float, perché non implementare semplicemente tre metodi (o gruppi di tre metodi), con lo stesso nome e in overload, che gestiscono tali tipi di dati?

    Scomodare i Generics per un segnaposto che virtualmente accetta qualsiasi tipo di dato per limitare la scelta a tre alternative mi sembra sprecato oltreché una complicazione estrema e che non porta a nessun reale vantaggio di alcun tipo.

    Ciao!
  • Re: Generics con Where multipli: è possibile?

    Salve a tutti, e grazie per le risposte, sempre ottime, come sempre.
    Sinceramente l'implementazione tramite Generics era un modo anche per approfondire il concetto, pensando magari che si potesse fare una cosa tipo: Where Tipo1 Or Tipo2 Or Tipo3.
    Alla fine ho fatto l'overloading di due metodi, preferendo separare l'arrotondamento per eccesso da quello per difetto per chiarezza; i metodi reali sono due che usano dei double (Math.Truncate e Math.Ceiling).
    Nelle note di documentazione per i tipi Float e Decimal ho inserito questo comportamento, come avvertenza.
    Vi ringrazio ancora per la possibilità di confrontarmi e vi auguro buon weekend.
    Lucius
Devi accedere o registrarti per scrivere nel forum
3 risposte