Here we go. First, the class has no need to be `abstract` as it has no `virtual` members. In fact, since it has all `static` members, the class should also be `static`. Also followed C# naming conventions, in which local variables should be `camelCased` rather than the `PascalCased` you have. Used some LINQ to declare intent rather than implementation by using `.Any()` in a few places. Also re-declared `List<Node>` throughout as `IList<Node>` since programming to interfaces is better for decoupling. For that matter, wherever `Node` lives, may want to extract an `INode` interface from it and use it here. Finally, a tiny performance improvement: don't allocate the lists until after the base case has been evaluated (and returned from) so the GC doesn't have as much pressure on it. namespace prjT02L08_Predator_Prey { using System.Collections.Generic; using System.Linq; public static class MergeSort { public static IList<Node> Sort(IList<Node> input) { if (input.Count <= 1) { return input; } var midpoint = input.Count / 2; IList<Node> left = new List<Node>(); IList<Node> right = new List<Node>(); for (var i = 0; i < midpoint; i++) { left.Add(input[i]); } for (var i = midpoint; i < input.Count; i++) { right.Add(input[i]); } left = Sort(left); // Recursion! :o right = Sort(right); return Merge(left, right); } private static IList<Node> Merge(IList<Node> left, IList<Node> right) { var result = new List<Node>(); while (left.Any() && right.Any()) { if (left[0].F < right[0].F) { result.Add(left[0]); left.RemoveAt(0); } else { result.Add(right[0]); right.RemoveAt(0); } } while (left.Any()) { result.Add(left[0]); left.RemoveAt(0); } while (right.Any()) { result.Add(right[0]); right.RemoveAt(0); } return result; } } }