0

Is the following loop approach, using TryGetTarget then compare the proper way?

void Remove<T>( List<WeakReference<T>> list, T toRemove ) where T : class {
    for(var i=0; i<list.Count; ++i) {
        if(list[i].TryGetTarget(out var el) && el==toRemove) {
            list.RemoveAt(i);
            break;
        }
    }
}

Is there a more elegant or suggested way to do this?

kuskmen
  • 3,648
  • 4
  • 27
  • 54
somebody4
  • 505
  • 4
  • 14
  • 1
    Do you have any particular concern about that approach? – Jon Skeet May 30 '18 at 11:26
  • Just want to see if there is more elegant way. – somebody4 May 30 '18 at 11:28
  • 1
    Seems correct here. The `++i` is quite ugly and is very old school (when `++i` was waster than `i++`, [but only for specific advanced cases](https://stackoverflow.com/questions/24901/is-there-a-performance-difference-between-i-and-i-in-c)) – xanatos May 30 '18 at 11:28
  • Are you certain that there'll only be one such reference, or that you only wish to remove one? Otherwise, `list.RemoveAll(wr => wr.TryGetTarget(out var el) && el == toRemove)` would work well too. – Jon Skeet May 30 '18 at 11:30
  • 1
    @xanatos yeah, old c++ habit. – somebody4 May 30 '18 at 11:31

1 Answers1

1

You could probably shorten it to:

list.RemoveAll(item => item.TryGetTarget(out var el) && el == toRemove);
nvoigt
  • 75,013
  • 26
  • 93
  • 142
  • There is a difference here... `RemoveAll` will look at duplicates (so it will parse all the elements), he is doing a "`RemoveFirst`". – xanatos May 30 '18 at 11:31
  • I was just adding a comment adding the same thing. It behaves slightly differently though: 1) it may remove more than one item; 2) it won't stop when it's found the first item, potentially causing a difference in performance. – Jon Skeet May 30 '18 at 11:31
  • hm, true, I figured that "Remove items" in the headline meant that actually removing those items is the goal... Let's see what the OP says. – nvoigt May 30 '18 at 11:32
  • Actually the code is for demo. I want see if it is suggested to use a TryGetTarget then compare or something like ReferenceEquals. May be I am not clear. – somebody4 May 30 '18 at 11:38
  • @somebody4 If T is a reference, then `==` is converted to `ReferenceEquals`. Compare on [SharpLab](https://sharplab.io/#v2:C4LglgNgPgAgDAAhgRgNwFgBQMDMSBMCAwggN5YKVJ4BGA9nRAgLLIA8AKgHwAUHCAQ2QAaBPwH4AlAgDuACwCmAJwViEIAmQpUdMAOwI6NAFYKAxsAB0AJQUAzZQoB2ZhQFEAjgFcBEAM48QqISkhiYOgC+WNqUuAj0jCz4nLziImohsooqahowhOThOlT6gsgIALwVgvhhkVgRQA==) the IL Code – xanatos May 30 '18 at 11:48