It's not a good idea to change state of the class the way you do it here only to return the field as a result:

>     private int _currentIndex;
>     private string _outputGrid;
> 
>     public string CalculateNextGrid(string inputGrid, int gridSize)
>     {
>         _outputGrid = "";
>         _currentIndex = 0;
>     
>         ...
>
>         return _outputGrid;
>     }

This is not thread safe. Should you ever want to use a single instance of it with multiple threads they will overwirte each other's work. Most of the fields could be local to the functions making them [pure](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/linq/refactoring-into-pure-functions) ones and thus much easier to use and to maintain.

> [..] a pure function has two useful characteristics:

> - It has no side effects. The function does not change any variables or the data of any type outside of the function.

> - It is consistent. Given the same set of input data, it will always return the same output value.