1

Situation :

I have a List<DataGridView> temp. I need to pass a specific index to a function by reference, because I loop through them and I need to change the one affected. Here are the methods I tried/used

Method 1

functionA(ref temp[0]);
A property, indexeur or access to a dynamic member cannot be passed as ref or out (free traduction)

However that I can do :

Method 2

DataGridView bobu = temp[0];
functionA(ref bobu );

And this work. Would there be a way to use my method 1 instead of using a trick like in method 2?

Cher
  • 2,789
  • 10
  • 37
  • 64
  • 1
    I don't think 1 and 2 are equivalent. In method 1 you try to give reference to temp[0] which would allow you to reassign the 'DataGridView' in "slot" 0 of the List. Method 2 however allows you to do the same on `bobu` which if you reassign that in `functionA` it has no effect on `temp[0]` – Frank J Jul 13 '15 at 17:19
  • @FrankJ But changing the properties of `bobu` *would* change `temp[0]` since `DataGridView` is a class, not a struct. What I don't understand is why `ref` is even here, since `DataGridView` is already a reference type. – Jashaszun Jul 13 '15 at 17:20
  • exactly what happens!! But would there be a way not to need tampon variable? And sorry about variable names, will use better ones next time! – Cher Jul 13 '15 at 17:22
  • 1
    You can change the contents of the `DataGridView` sure if that is all you want you do not need a reference at all because it is a reference type. You only would need it if you would like to `new` up a new instance of a `DataGridView` inside `functionA` assign it to that variable that was passed in and want to see the change outside of the function. If you know C++ this concept is akin to double pointers. – Frank J Jul 13 '15 at 17:23
  • 1
    Look at [this from MSDN](https://msdn.microsoft.com/en-us/library/14akc2c7.aspx) for how to use `ref`. – Frank J Jul 13 '15 at 17:27
  • thanks a lot!! yes I'm akin to C++ (and not to C#) but if I compare to C++, of course I understand that it doesn't need a ref!! If you post this as answer I will mark it for future people who have this question!! thanks again!! – Cher Jul 13 '15 at 17:28
  • Glad to help. [Here is another link](https://msdn.microsoft.com/en-us/library/3ewxz6et.aspx) that shows the difference between value types and reference types which will help you with your transition from C++ to C#. – Frank J Jul 13 '15 at 17:53

3 Answers3

2

Similar question has been asked multiple times earlier too, following links should help:

What is the use of "ref" for reference-type variables in C#?

Idea remains ref or out keywords are like reference to a reference, like pointer to a pointer, so they can be used to change the reference to a different allocation all together. In regular case, it would be passing reference by value, so even when values of fields and properties could be changed, but original memory reference can't be changed.

We cannot use a ref keyword for the property, indexer, since it cannot be ascertain whether they have implemented a setter or its read only, therefore you need to copy to a variable, as you have done, which has no such issue, whether it's writable or not, check the following discussion:

C# property and ref parameter, why no sugar?

As already suggested for changing values in the DataGridView, you can pass the simple type, which can modify the object accessible properties / fields

Community
  • 1
  • 1
Mrinal Kamboj
  • 11,300
  • 5
  • 40
  • 74
1

Based on your comments it sounds like you only want to change the properties of the item in the list, not change the list to reference a different item. In that case ref is not necessary since DataGridView is a reference type - meaning that when you pass a variable to a function you are actually passing a reference to an object (which is not the same as "pass-by-reference").

Just take ref out of the method signature and the calling syntax and you will be fine.

If you do want to change the object within the list, then you need to pass the list to the method and some way to identify which object you want to update (e.g. the index):

public void functionA(List<DataGridView> list, int index)
{
    list[index] = {some new object}
}

Note that ref is not needed in this case either since List<T> is also a reference type.

D Stanley
  • 149,601
  • 11
  • 178
  • 240
0

For this purpose I've implemented a Generic Wrapper to hold the reference where the reference can be initialized by one of two ways, passing the object itself or the List and the index, and has a getter and a setter

public class Ref<T>
{
    private T _ref;
    private IList<T> list;
    private int index;

    public Ref(T _ref)
    {
        this._ref = _ref;
    }

    public Ref(IList<T> list, int index)
    {
        this.list = list;
        this.index = index;
    }

    public void set(T _ref)
    {
        if (this._ref == null)
        {
            this.list[index] = _ref;
        }
        else
        {
            this._ref = _ref;
        }
    }

    public T get()
    {
        if (this._ref == null)
        {
            return this.list[index];
        }
        else
        {
            return this._ref;
        }
    }

}

instead of passing by reference, pass a Ref of the required type

Mohamed Ali
  • 3,717
  • 1
  • 33
  • 39