-1

I am writing a function which is passed in a list which is partially filled. I'd like to set some of the fields within the list inside this function. I thought that passing it as a reference would allow me to do this, however, I get the following error:

Error 1 Cannot modify the return value of 'System.Collections.Generic.List.this[int]' because it is not a variable

I am wondering what I might need to do to tell C# that I wish to have the option of modifying the contents of the list.

Here is a summarized version of my code:

    public static void Determine_RTMM_Descriptor(ref List<Struct_Descriptor_Type> symbols, string Dwarf_Output_Filename)
    {
        ...
        lines = System.IO.File.ReadAllLines(Dwarf_Output_Filename);

        //loop on symbol names
        for (int idx = 0; idx < symbols.Count; idx++)
        {

            if(symbols[idx].size == 0) 
                symbols[idx].size = (int)new System.ComponentModel.Int32Converter().ConvertFromString(split_line[DwarfInterface.SIZE_INDEX]);

        ...
    }

Thanks in advance for any help.

Michael Bauer
  • 183
  • 4
  • 15
  • 1
    It's passed in by reference by default, no need for ref – frenchie Apr 29 '14 at 16:38
  • You almost certainly shouldn't be using a `struct`, and should instead be using a `class`. The error that you're seeing is just one of the many reasons why mutable structs are evil; that you aren't familiar with it means that you'll most likely do all sorts of other Bad Things that the compiler *can't* catch for you. – Servy Apr 29 '14 at 16:42

2 Answers2

3

The underlying issue here is that you have a list of value types. When you use the indexer of the list to get an item from the list you are getting a copy of that type. The code symbols[idx] is the value of that item. It is not a variable representing that item, as the error message is telling you.

You're trying to mutate the size of the copy, which will have no effect on the item of the list. This is such a common mistake that the compiler even makes this an error.

If you really are sure that you want to have a mutable value type (hint: you aren't, and you shouldn't have one; you almost certainly just want to have a class here to avoid this problem entirely) then you would need to get the value of the item, mutate it, and then set the item again:

if(symbols[idx].size == 0) 
{
    var symbol = symbols[idx];
    symbol.size = 42;
    symbols[idx] = symbol;
}
Servy
  • 202,030
  • 26
  • 332
  • 449
-2

Your return type on the function is "void" when you should set the return type to the list. That should allow you to change it and return it modified.

Dean.DePue
  • 1,013
  • 1
  • 21
  • 45
  • 1
    1) There's no need to return the list; he can just mutate the parameter as he's not creating a new list 2) This doesn't address the error message brought up in the question at all. – Servy Apr 29 '14 at 16:47
  • I agree, he can just change the parameter, but he can also return the modified list, which I have done many times. And it certainly does answer his question. There's no need to down vote my answer, it is an answer! – Dean.DePue Apr 29 '14 at 17:03
  • What is the point in redundantly returning the mutated list? It is accomplishing *nothing*, nor is it enabling anything for the caller, as they already have access to the list; they couldn't call the method without it. And no, your answer isn't an answer to the question; it is not explaining why he's getting the error that he's getting, merely suggesting a change that changes nothing. – Servy Apr 29 '14 at 17:04