In breve: è possibile definire un metodo generico in cui il parametro type (T
) è vincolato a string
o int[]
? In pseudo-C#, quello che voglio fare è:È possibile vincolare un parametro di tipo generico a String OR Array
public static int MyMethod<T> (T arg1, T arg2)
where T : (has an indexer that returns an int) {
// stuff with arg1[i], arg2[j], etc...
}
Si noti che in C#, a causa del built-in string
indicizzatore (che restituisce una char
) con conversione implicita da char
al int
, la seguente espressione significa esattamente la stessa cosa se source
è un string
o un int[]
:
int someval = source[index];
per il filo Constrain generic extension method to base types and string mi rendo conto che non posso solo fare un elenco dei tipi non associati nel where T : x...
clausola di vincolo. Entrambi int[]
e string
sono conformi a T: IEnumerable<int>
, ma IEnumerable<T>
non richiede agli implementatori di avere un indicizzatore, che è esattamente la caratteristica comune che sto utilizzando da entrambi i tipi.
Lo scopo di questo è che sto creando alcune funzioni di analisi e analisi delle stringhe altamente ottimizzate, come una rapida implementazione dell'algoritmo di distanza Damerau-Levenshtein. Ho scoperto che per prima cosa la conversione delle stringhe in matrici di int può talvolta produrre esecuzioni significativamente più veloci nell'elaborazione ripetitiva di carattere per carattere (come con l'algoritmo D-L). Ciò è in gran parte dovuto al fatto che confrontare i valori int
è molto più veloce rispetto ai valori char
.
La parola chiave è "a volte". A volte è più veloce operare direttamente sulle stringhe ed evitare il costo della prima conversione e copia negli array di int
. Quindi ora ho metodi che sono veramente identici tranne che per le dichiarazioni.
Naturalmente posso usare dynamic
, ma la penalità delle prestazioni dal controllo in fase di esecuzione distrugge completamente i guadagni realizzati nella costruzione dei metodi. (I ha effettuato il test).
In che senso è sensato trattare 'T' staticamente * * * un tipo o un altro? Il punto di vincoli è quello di consentire di operare su variabili di tipo "T" e prevedere un livello minimo di compatibilità del tipo. Vincolare a due tipi incompatibili tra loro è bizzarro. –
@ kirk-woll: Come descrivo in dettaglio, non sono reciprocamente incompatibili per i miei scopi. Al contrario, sono identici. Ho costruito e sto usando metodi che sono identici al 100%, tranne che i parametri in una versione sono dichiarati come 'stringa' e nell'altra versione sono dichiarati come' int [] '. In entrambi i casi, sto operando su ciascun membro della raccolta come un numero intero. –
No. Una 'stringa' e (qualsiasi)' matrice' unifica a 'oggetto', una stringa * non * un' carattere [] 'in C#, sebbene sia possibile creare un' char [] '* da * una stringa , ma questo è un * nuovo * oggetto array con i contenuti copiati. –