Является ли следующий подход цикла, используя TryGetTarget, затем правильно сравнивать?
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;
}
}
}
Есть ли более элегантный или предлагаемый способ сделать это?
Просто хочу посмотреть, есть ли более элегантный способ.
Здесь кажется правильным. ++i довольно уродлив и очень старой школы (когда ++i был потрачен впустую, чем i++, но только для особых случаев)
Вы уверены, что будет только одна такая ссылка или что вы хотите удалить только одну? В противном случае подойдет и list.RemoveAll(wr => wr.TryGetTarget(out var el) && el == toRemove).
@xanatos да, старая привычка к C++.





Вероятно, вы могли бы сократить его до:
list.RemoveAll(item => item.TryGetTarget(out var el) && el == toRemove);
Здесь есть разница ... RemoveAll будет смотреть на дубликаты (чтобы проанализировать все элементы), он делает "RemoveFirst".
Я просто добавлял комментарий, добавляя то же самое. Однако он ведет себя немного иначе: 1) он может удалить более одного элемента; 2) он не остановится, когда найдет первый элемент, что может вызвать разницу в производительности.
хм, правда, я подумал, что «Удалить элементы» в заголовке означает, что фактическое удаление этих элементов является целью ... Давайте посмотрим, что говорит OP.
На самом деле код предназначен для демонстрации. Я хочу посмотреть, предлагается ли использовать TryGetTarget, а затем сравнить или что-то вроде ReferenceEquals. Может быть, я не совсем понимаю.
@ something4 Если T является ссылкой, то == преобразуется в ReferenceEquals. Сравните на SharpLab Код IL
Есть ли у вас какие-либо особые опасения по поводу такого подхода?