LeetCode: Spiral Matrix II C#
If n is zero then the loop

while (startCol &lt;= endCol &amp;&amp; startRow &lt;= endRow)


does nothing, which means that the test

if (n == 0)


is not necessary.

Here

for (int i = endCol; i &gt;= startCol; i--)
{
    //keep in mind this is a spiral we can be in a line we are not suppose to touch the values
    //only in the upper half of the matrix we need
    if (startRow &lt;= endRow)
    {
        res[endRow][i] = num++;
    }
}


the condition of the if-statement is a loop invariant, so that it can be done outside of the loop:

if (startRow &lt;= endRow)
{
    for (int i = endCol; i &gt;= startCol; i--)
    {
        res[endRow][i] = num++;
    }
}


Even if the C# compiler is smart enough to recognize the loop invariant and reorders the statements, the latter variant would be clearer to the reader of your code. The same applies to the next loop in your function.

Then note that startRow/startCol and endRow/endCol have the same value at the start of the loop body, and the tests 

if (startRow &lt;= endRow) ...
if (startCol &lt;= endCol) ...


can fail only in the last iteration. Therefore one can move that case out of the main loop, use only two variables for the first and last row/column, and write the inner loops in a symmetric fashion:

int start = 0;
int end = n - 1;

while (start &lt; end)
{
    for (int i = start; i &lt; end; i++)
    {
        res[start][i] = num++;
    }
    for (int i = start; i &lt; end; i++)
    {
        res[i][end] = num++;
    }
    for (int i = end; i &gt; start; i--)
    {
        res[end][i] = num++;
    }
    for (int i = end; i &gt; start; i--)
    {
        res[i][start] = num++;
    }

    start++;
    end--;
}

if (start &lt;= end)
{
    res[start][start] = num;
}