This is a significantly more efficient solution than the others posted here, especially the top solution:
bool isSubset = t2.All(elem => t1.Contains(elem)); If you can find a single element in t2 that isn't in t1, then you know that t2 is not a subset of t1. The advantage of this method is that it is done all in-place, without allocating additional space, unlike the solutions using .Except or .Intersect. Furthermore, this solution is able to break as soon as it finds a single element that violates the subset condition, while the others continue searching. Below is the optimal long form of the solution, which is only marginally faster in my tests than the above shorthand solution.
bool isSubset = true; foreach (var element in t2) { if (!t1.Contains(element)) { isSubset = false; break; } } I did some rudimentary performance analysis of all the solutions, and the results are drastic. These two solutions are about 100x faster than the .Except() and .Intersect() solutions, and use no additional memory.