Although I am very late, I want to give an alternative answer to the question.
The first important part of the question was to be able to access the full rows OR columns of the matrix. One way to do this is to use extension methods:
public static class MatrixExtensions {
Usage example:
double[,] myMatrix = ...
First of all, it should be noted that you can use these general methods with any [,] - matrices and corresponding [] -vectors. Imagine replacing T with double s, and you will get a specific version for "double" (as OP was asked).
Secondly, getting and setting up rows uses Array.Copy , and when getting and setting columns, a loop is used. This is due to the C # string order , which allows you to use the first, but not the second. Of course, both can be implemented using a loop, as can be seen from the comments.
Be sure to pass the correct sizes for set-Methods, or the program will fail (error and size checking can be easily added). All logic can also be implemented for gear arrays, such as double[][] , but the OP specifically requested multidimensional ones.
As for the second part of the question: if your matrix consists of double and double is a value type, the values will always be copied. Therefore, your desired behavior of not copying values would be impossible. However, if you use objects like T , only the link pointing to the object will be copied, not the object itself (therefore, you should not mutate the "copied" object).
Finally, if you really do not want to copy double values, I would suggest passing your entire matrix (only this link is passed), and then directly sorting through the columns and / or rows you need.