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.

questionAnswers(5)

yourAnswerToTheQuestion