Finding all neighbors of any given element in a matrix like structure This is the code I currently have to get all neighbors of any given element in a matrix like structure:

struct Coordinates: IEquatable&lt;Coordinates&gt;
{
    public int Row { get; }
    public int Column { get; }

    public Coordinates(int row, int column)
    {
        Row = row;
        Column = column;
    }

    public bool Equals(Coordinates other) =&gt; Column == other.Column &amp;&amp; Row == other.Row;

    public override bool Equals(object obj)
    {
        if (obj is Coordinates)
        {
            return Equals((Coordinates)obj);
        }

        return false;
    }

    public override int GetHashCode() =&gt; unchecked(27947 ^ Row ^ Column); 

    public IEnumerable&lt;Coordinates&gt; GetNeighbors(int numberOfRows, int numberOfColumns)
    {
        var increasedRow = Row + 1;
        var decreasedRow = Row - 1;
        var increasedColumn = Column + 1;
        var decreasedColumn = Column - 1;
        var canIncreaseRow = increasedRow &lt; numberOfRows;
        var canIncreaseColumn = increasedColumn &lt; numberOfColumns;
        var canDecreaseRow = decreasedRow &gt; -1;
        var canDecreaseColumn = decreasedColumn &gt; -1;

        if (canDecreaseRow)
        {
            if (canDecreaseColumn)
            {
                yield return new Coordinates(decreasedRow, decreasedColumn);
            }

            yield return new Coordinates(decreasedRow, Column);

            if (canIncreaseColumn)
            {
                yield return new Coordinates(decreasedRow, increasedColumn);
            }
        }

        if (canIncreaseRow)
        {
            if (canDecreaseColumn)
            {
                yield return new Coordinates(increasedRow, decreasedColumn);
            }

            yield return new Coordinates(increasedRow, Column);

            if (canIncreaseColumn)
            {
                yield return new Coordinates(increasedRow, increasedColumn);
            }
        }

        if (canDecreaseColumn)
        {
            yield return new Coordinates(Row, decreasedColumn);
        }

        if (canIncreaseColumn)
        {
            yield return new Coordinates(Row, increasedColumn);
        }
    }
}


This works but it seems kind of clunky and I can't help thinking there is a more elegant, concise and obvious way of doing this.

Considerations to take into account:


By elegant I mean more concise but readable and mantainable even if performance is slightly worse.
I don't want dependencies on System.Drawing.Point or similar because I don't want to use mutable structs and I don't like using types that conceptually represent unrelated things even though they happen to provide usable functionality to solve the problem at hand.
There is no bound checking in the arguments. This is simply because the code where I'm using this algorithm already ensures that the current coordinates instance is a valid location. As per comments, the current implementation will give erroneous results if you happen to enter matrix bounds that makes the current coordinates invalid. This is not an issue that concerns me.
You could use a 2-dimensional loop to iterate over neighbors as follows:

public IEnumerable&lt;Coordinates&gt; GetNeighbors(int numberOfRows, int numberOfColumns)
{
    var canIncreaseRow = Row &lt; numberOfRows - 1;
    var canIncreaseColumn = Column &lt; numberOfColumns - 1;
    var canDecreaseRow = Row &gt; 0;
    var canDecreaseColumn = Column &gt; 0;

    var maxRow = canIncreaseRow ? Row + 1 : Row;
    var minRow = canDecreaseRow ? Row - 1 : Row;
    var maxColumn = canIncreaseColumn ? Column + 1 : Column;
    var minColumn = canDecreaseColumn ? Column - 1 : Column;

    for (int row = minRow; row &lt;= maxRow; row++)
    {
        for (int column = minColumn; column &lt;= maxColumn; column++)
        {
            if (row != Row || column != Column)
            {
                yield return new Coordinates(row, column);
            }
        }
    }
}