Here’s a nice quick solution. Let’s say you have some List<T> and you need to separate it into chunks of some number N or less, for example taking 100 numbers and separating them into batches of 25.

List<int> myListOfNumbers = Enumerable.Range(1, 100).ToList();

var parted = Enumerable.Range(0, myListOfNumbers.Count)
						.GroupBy(n => n / 25) // <-- clever sleight of hand here
						.Select(n => n.Select(index => myListOfNumbers[index]).ToList());

// prints 1-24, 25-49, 50-74, 75-100
foreach (var part in parted) {
	Debug.WriteLine(String.Join(",", part.Select(p => p.ToString())));
}


The sleight of hand I’m noting is a neat trick with integer division truncating or flooring values. You can fairly easily generalize this into a method where you pass a List<T> and a parameter for how many items you want in a group.

Func<List<int>, int, IEnumerable<List<int>>> splitList = (list, groupSize) => {
	return Enumerable.Range(0, list.Count)
						.GroupBy(n => n / groupSize) 
						.Select(n => n.Select(index => list[index]).ToList());            
};

List<int> primes = new List<int>(){ 2, 3, 5, 7, 11, 13, 17 };
var primesGrouped = splitList(primes, 3);


Pretty cool no?