0

I'm creating a matrix class so I already have a

public double this[int row, col]

but I'd also want to easily set and get a particular row or column in a similar fashion. I currently have:

public virtual Vector GetRow(int row)
{
    return m[row];
}

public virtual void SetRow(int row, Vector v)
{
    m[row] = v;
}

public virtual Vector GetCol(int col)
{
    return Transpose().m[col];
}

public virtual void SetCol(int col, Vector v)
{
    Matrix temp = Transpose();
    temp.SetRow(col, v);
    temp =  temp.Transpose();
    m = temp.m;
}

but what I want is something like:

public virtual Vector Row(int row)
{
    get => return m[row];
    set => m[row] = value;
}

public virtual Vector Col(int col)
{
    // getter and setter logic here
}

is there a way to do this? or do I absolutely NEED to use the methods I've created? I know that I could do the row OR the column the way that I want, but, not both I don't think.

smn.tino
  • 2,272
  • 4
  • 32
  • 41
Raxmo
  • 57
  • 5
  • no you need to define **Properties** or you define a function that take **paramenter** string that responsible for return and set the value. – Muhammad Usama Alam Jul 19 '18 at 10:54
  • Can you demonstrate how you'd expect to call these things? – Ant P Jul 19 '18 at 10:57
  • 1
    You can try with the new `ref` return syntax, something like this: `public virtual ref Vector Row(int row) => ref m[row];`, and use `Row(n) = value`. – Alessandro D'Andria Jul 19 '18 at 10:58
  • @AlessandroD'Andria the pass by reference is a rather smart idea, something that I should definitely keep in mind for future things. Seems like something that is incredibly useful in many situations, especially when working with data structures like matrices and tensors. – Raxmo Jul 19 '18 at 11:14

3 Answers3

1

For this you need to understand the concept of properties, let's have a look at Microsoft docs:

Properties combine aspects of both fields and methods. To the user of an object, a property appears to be a field, accessing the property requires the same syntax. To the implementer of a class, a property is one or two code blocks, representing a get accessor and/or a set accessor. The code block for the get accessor is executed when the property is read; the code block for the set accessor is executed when the property is assigned a new value. A property without a set accessor is considered read-only. A property without a get accessor is considered write-only. A property that has both accessors is read-write.

Unlike fields, properties are not classified as variables. Therefore, you cannot pass a property as a ref or out parameter.

this line is important: Unlike fields, properties are not classified as variables. Therefore, you cannot pass a property as a ref or out parameter.

Meaning: you cannot pass parameters to get and set properties. They are here as Accessors - they act like variables in a manner of read\write into the property but you cannot treat them as fields.

Why do they exist?

  1. Saying get and set in the beginning of every access or mutation of a value is annoying and distracting.

  2. Providing direct access to the actual variable breaks encapsulation, so that's not an option.

meaning, they are here to help as with OO programming conecpt - keep the encapsulation and they are an easier way of assigning values into variables in our program.

Barr J
  • 10,636
  • 1
  • 28
  • 46
0

All indexers in c# are named this. They can be overloaded so you can also implement:

public Vector this[int row]

Exactly as you did for public double this[int row, col]. However, we'll note that the indexes for columns and rows are the same type, so you can only do this for rows or columns (since you can't have two overloads with identical signatures). At this point, you have to decide whether the benefit of doing this outweighs the breaking of symmetry.

Damien_The_Unbeliever
  • 234,701
  • 27
  • 340
  • 448
0

so, after giving it a little thought while you guys unloaded on this question (loads of helpful info by the by ^-^) I've come to a solution that works quite well

    public enum RowCol {row, col}

    public Vector this[RowCol set, int rowcol]
    {
        get
        {
            switch (set)
            {
                case RowCol.col:
                    return Transpose().m[rowcol];

                default:
                    return m[rowcol];
            }
        }
        set
        {
            switch (set)
            {
                case RowCol.col:
                    Matrix temp = Transpose();
                    temp[RowCol.row, rowcol] = value;
                    temp = temp.Transpose();
                    m = temp.m;
                    break;

                default:
                    m[rowcol] = value;
                    break;
            }
        }
    }

so, I think this is the best solution for my particular implementation. Thank you for all the input and info.

EDIT: I ended up going with this solution rather than a ref because the rows are vectors, but the columns are a constructed value due to the fact that in order to store the columns, I'd have to have two variables of the same data, one set up for the rows, and the other set up for the columns. Which seems rather wasteful to me, and i'd still need to figure out a way to sync the two variables anyway.

Raxmo
  • 57
  • 5
  • Glad you found a solution but in general I would question what value this gives you over a method except to add some obscurity to the calling code. – Ant P Jul 19 '18 at 14:17
  • @AntP mainly for the sake of sanity. Given that I already understand Matrices from the mathematical definition, thus, I'd like the code to be closer to how I'd write the functions out on paper as much as I can. – Raxmo Jul 20 '18 at 09:32