Ho scritto un metodo di estensione in csharp per un helper Html MVCContrib e sono rimasto sorpreso dalla forma del vincolo generico, che a prima vista sembra circolare riferimento stesso attraverso il parametro type.Perché questo compilatore generico viene compilato quando sembra avere un riferimento circolare
Ciò detto, il metodo compila e funziona come desiderato.
Mi piacerebbe che qualcuno spiegasse perché questo funziona e se esiste una sintassi intuitiva più intuitiva e se no qualcuno sa perché?
Questo è il codice di compilazione e funzione ma ho rimosso l'elenco di esempio T durante l'offuscamento del problema.
e un metodo analogo utilizzando un elenco <T>.
namespace MvcContrib.FluentHtml
{
public static class FluentHtmlElementExtensions
{
public static TextInput<T> ReadOnly<T>(this TextInput<T> element, bool value)
where T: TextInput<T>
{
if (value)
element.Attr("readonly", "readonly");
else
((IElement)element).RemoveAttr("readonly");
return element;
}
}
}
/*analogous method for comparison*/
public static List<T> AddNullItem<T>(this List<T> list, bool value)
where T : List<T>
{
list.Add(null);
return list;
}
Nel primo metodo il vincolo T: TextInput <T> sembra a tutti gli effetti, circolare. Tuttavia, se io commento fuori ottengo un errore di compilazione:
"Il tipo di 'T' non può essere utilizzato come parametro di tipo 'T' nel tipo generico o il metodo 'MvcContrib.FluentHtml.Elements.TextInput <T>' Non c'è conversione di boxe o conversione di parametri di tipo da "T" a "MvcContrib.FluentHtml.Elements.TextInput <T>". "
e nell'elenco delle <T> caso l'errore (s) sono:
"La partita metodo migliore overload per 'System.Collections.Generic.List.Add (T)' ha qualche argomenti non validi argomento 1: impossibile convertire da '<nullo>' a 'T'"
ho potuto immaginare una definizione più intuitiva sarebbe uno che comprende 2 tipi, un riferimento t o il tipo generico e un riferimento di vincoli Tipo es:
public static TextInput<T> ReadOnly<T,U>(this TextInput<T> element, bool value)
where U: TextInput<T>
o
public static U ReadOnly<T,U>(this U element, bool value)
where U: TextInput<T>
ma nessuno di questi compilazione.
Come è stato risposto già questo non è circolare, tuttavia, come una nota a margine è la possibilità di creare ereditarietà circolare che a volte compila e talvolta no (come aggiungere, rimuovere o rinominare file e cartelle può far sì che la compilazione abbia esito positivo o negativo). Quindi esistono bug con eredità circolare. (VS2010) – AnorZaken