Por que essa restrição genérica é compilada quando parece ter uma referência circular
Eu escrevi um método de extensão no csharp para um auxiliar MVCContrib Html e fiquei surpreso com a forma da restrição genérica, que aparentemente parece se referir circularmente por meio do parâmetro type.
Dito isto, o método compila e funciona como desejado.
Eu gostaria que alguém explicasse por que isso funciona e se uma sintaxe intuitiva mais intuitiva, x existe e, se não, se alguém sabe o porquê?
Aqui está o código de compilação e função, mas eu removi o exemplo da Lista de T, uma vez que nublava o problema.bem como um método análogo usando uma Lista <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;
}
No primeiro método, a restrição T: TextInput <T> parece circular, para todos os efeitos. No entanto, se eu comentar, recebo um erro do compilador:
"O tipo 'T' não pode ser usado como parâmetro de tipo 'T' no tipo ou método genérico 'MvcContrib.FluentHtml.Elements.TextInput <T>'. Não há conversão de boxe ou conversão de parâmetro de tipo de 'T' para 'MvcContrib .FluentHtml.Elements.TextInput <T> '. "
e no caso da lista <T>, os erros são:
"A melhor correspondência de método sobrecarregado para 'System.Collections.Generic.List.Add (T)' possui alguns argumentos inválidos Argumento 1: não é possível converter de '<null>' para 'T'"
Eu poderia imaginar que uma definição mais intuitiva seria aquela que inclui 2 tipos, uma referência ao tipo genérico e uma referência ao tipo de restrição, por exemplo:
public static TextInput<T> ReadOnly<T,U>(this TextInput<T> element, bool value)
where U: TextInput<T>
ou
public static U ReadOnly<T,U>(this U element, bool value)
where U: TextInput<T>
mas nenhum deles compila.