2

snippets of my code

List<List<optionsSort>> stocks = new List<List<optionsSort>>();
optionsSort tempStock1 = new optionsSort();
List<optionsSort> stock = new List<optionsSort>();

then some code,

for (int j = 1; j < optionsSt.Count; j++)
{

            if (optionsSt[j].isin == optionsSt[j - 1].isin)
            {

                tempStock1.name = optionsSt[j].name;
                tempStock1.date = optionsSt[j].date;
                tempStock1.strike = optionsSt[j].strike;
                tempStock1.size = optionsSt[j].size;
                tempStock1.isin = optionsSt[j].isin;
                tempStock1.callPut = optionsSt[j].callPut;

                stock.Add(tempStock1);

            }
            else
            {

                stocks.Add(stock);

                k = k + 1;
                stock.Clear();

                tempStock1.name = optionsSt[j].name;
                tempStock1.date = optionsSt[j].date;
                tempStock1.strike = optionsSt[j].strike;
                tempStock1.size = optionsSt[j].size;
                tempStock1.isin = optionsSt[j].isin;
                tempStock1.callPut = optionsSt[j].callPut;

                stock.Add(tempStock1);



            }




        }//endfor

Basicly, im going through a large list to sort elements into groups, a new List name stocks.

now the problem is, when I add to stocks all elements contained in the list stock and then clear stock on the next line to start again, I delete all the elements I have stored in stocks.

Any Ideas. Do I have to index stocks like stocks[i].Add(stock) so each block of similar stocks is an element in stocks.

Thanks for any help.

Timujin
  • 171
  • 1
  • 4
  • 14

2 Answers2

3

The problem is that List<T> objects, like all classes in .NET, are reference types. That means that every time you add stock to stocks you aren't adding a new list, you are only adding a reference to the same list in memory. So when you later call Clear, that is reflected both in your variable stock and in all other references in stocks.

You can resolve this by making a shallow copy of stock every time you add it to stocks:

stocks.Add(stock.ToList());
p.s.w.g
  • 146,324
  • 30
  • 291
  • 331
  • I dont know how you would even know that, but I salute you... it fixed the problem.... ive been going mental over it!!! books dont teach you the tricks... – Timujin Jul 20 '13 at 13:54
  • 2
    @Timujin The difference between value and reference types is pretty fundamental to .NET programming. See [Value Types](http://msdn.microsoft.com/en-us/library/s1ax56ch.aspx) / [Reference Types](http://msdn.microsoft.com/en-us/library/490f96s2.aspx) – p.s.w.g Jul 20 '13 at 13:57
  • 2
    @Timujin I see that you're relatively new to Stack Overflow. If this or any other answer solved your problem, don't forget to accept it for the benefit of the future visitors who may have the same issue as you. Also, if any answer has helped you, please upvote it even if it wasn't the solution you ended up going with. This helps to encourage well researched, quality answers. – p.s.w.g Jul 20 '13 at 14:02
  • I am. I did vote up and it did Answer my question. already continued with my program :-) Many thanks for this, it has really helped. Im trying to get to grips with c#, requires time and practise I guess – Timujin Jul 20 '13 at 14:32
  • 1
    This answer helps with what the OP intended to **happen**, but not what he intended to **do**. `ToList()` is merely a hack in this case, at least IMHO. – Kendall Frey Jul 20 '13 at 14:36
  • 1
    @KendallFrey My interpretation of OP's code was that he intended to add a *copy* of `stock` to `stocks` on every iteration rather than adding a reference, and was reusing `stock` simply as a temporary variable--which is precisely how my answer works. In that case `Add(stock.ToList())` is just a shortened form of `Add(new List(stock))`. But +1 since your solution works just as well (and actually saves an array copy on each iteration). – p.s.w.g Jul 20 '13 at 14:57
  • Question. now that I have this list how would I iterate... for(i = 0; i – Timujin Jul 20 '13 at 15:03
  • 1
    @Timujin Either `foreach(x in stocks) foreach(y in x) ...` *or* `foreach(x in stocks.SelectMany(y => y)) ...`. – p.s.w.g Jul 20 '13 at 15:05
  • Thanks, I pressed return to quick and not "shift return". What im trying to do is this. some elements say in the 5 "row" of the list may contain the same date but because the size is different I want to add the 2 sizes together and get rid of one of the entries. so, for simplicity. if in stocks[0] there are 10 elements and of these 2 have the same date but are 2 different size, ill add those together and delete the one that is not the addition, so now in stocks[0] there will exist 9 elements – Timujin Jul 20 '13 at 15:09
  • 1
    @Timujin You can also do `for(var i = 0; i < stocks.Count; i++) for(var j = 0; j < stocks[i].Count; j++) ...` if you'd like to iterate the lists by index. Hopefully this answers your second question. – p.s.w.g Jul 20 '13 at 15:11
  • @p.s.w.g, i have this question here, if you have any insight? http://stackoverflow.com/questions/17764498/changing-the-value-of-certain-elements-of-a-list – Timujin Jul 20 '13 at 16:59
3

You're not creating a new list, you're using one list, and filling it and clearing it repeatedly. Since your outer list contains only one list, repeated multiple times, that list will have the same contents in every instance. That is, when you clear your list, you can no longer access the old contents, even if you try to access them from inside the outer list.

What you need to do is to change this line:

stock.Clear();

To this:

stock = new List<optionsSort>();

That is what you really meant. :)

Kendall Frey
  • 43,130
  • 20
  • 110
  • 148
  • Thanks. The method provided by P.S.W.G also works and works well. I get the desired results. Ill try yours aswell, maybe more ways to skin the cat :-) – Timujin Jul 20 '13 at 14:46