If you can change the consuming code to use an IReadOnlyList<T>, it's not too much work to write a wrapper class that will expose a column of a matrix (2D array) as an IReadOnlyList<T> vector.
This does add the proverbial "extra level of indirection", but it does also mean that the elements are returned without the need for any array allocations.
It's essentially working the same way as List<T> does - by wrapping an array - so it might be plenty fast enough for your needs.
Here's a sample implementation, with error handling elided for brevity:
(Also you can try this online)
public sealed class ArrayColumn<T>: IReadOnlyList<T>
{
public ArrayColumn(T[,] matrix, int column)
{
_matrix = matrix;
_column = column;
Count = _matrix.GetLength(0);
}
public IEnumerator<T> GetEnumerator()
{
IEnumerable<T> items()
{
for (int row = 0; row < Count; ++row)
{
yield return _matrix[row, _column];
}
}
return items().GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public int Count { get; }
public T this[int index] => _matrix[index, _column];
readonly T[,] _matrix;
readonly int _column;
}
With that implementation you can take a vertical slice from a matrix (2D array) and present it as a vector (1D array):
public static void Main()
{
var matrix = new string[5, 10];
for (int row = 0; row < matrix.GetLength(0); ++row)
{
for (int col = 0; col < matrix.GetLength(1); ++col)
{
matrix[row, col] = $"{row}, {col}";
}
}
var col3 = new ArrayColumn<string>(matrix, column: 3); // Grab column 3
for (int col = 0; col < col3.Count; ++col)
{
Console.WriteLine(col3[col]);
}
Console.WriteLine("-----------------");
foreach (var element in col3)
{
Console.WriteLine(element);
}
}
Output:
0, 3
1, 3
2, 3
3, 3
4, 3
-----------------
0, 3
1, 3
2, 3
3, 3
4, 3