The way you are using it makes no sense at all. But using a generic parameter in a constraint on that same parameter is quite normal, here's a more obvious example:
class MySortedList<T> where T : IComparable<T>
The constraint expresses the fact that there must be an ordering between objects of type T in order to put them into sorted order.
EDIT: I'm going to deconstruct your second example, where the constraint is actually wrong but helps it compile.
The code in question is:
/*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;
}
The reason it won't compile without a constraint is that value types can't be null
. List<T>
is a reference type, so by forcing where T : List<T>
you force T
to be a reference type which can be null. But you also make AddNullItem
nearly useless, since you can no longer call it on List<string>
, etc. The correct constraint is:
/* corrected constraint so the compiler won't complain about null */
public static List<T> AddNullItem<T>(this List<T> list)
where T : class
{
list.Add(null);
return list;
}
NB: I also removed the second parameter which was unused.
But you can even remove that constraint if you use default(T)
, which is provided for exactly this purpose, it means null
when T
is a reference type and all-zero for any value type.
/* most generic form */
public static List<T> AddNullItem<T>(this List<T> list)
{
list.Add(default(T));
return list;
}
I suspect that your first method also needs a constraint like T : class
, but since I don't have all the classes you're using I can't say for certain.