2014-01-10 2 views
2

У меня есть список элементов типа Texture (пользовательский класс с некоторыми свойствами). Я могу изменить данные одного из элементов в этом списке, но когда я их сохраняю, а в списке больше, чем один, он, похоже, делает новую копию в этом списке.Изменение элемента списка <Texture> создает новый элемент

Прежде всего это объявление списка Texture, который находится в статическом классе (MainData):

public static List<Texture> Textures = new List<Texture>(); 

А вот код, который изменяет данные в соответствии с, возможно, данные о том, что был заполнен пользователем:

for (int t = 0; t < MainData.Textures.Count; ++t) 
{ 
     if (MainData.Textures[t].Path == texture.Path) 
      MainData.Textures[t] = texture; 
     else 
      MainData.Textures.Add(texture); 
} 

Я понятия не имею, почему он это делает. И это происходит только в том случае, если в списке содержится более одного элемента. Есть ли что-то очевидное? Я ошибаюсь в этом?

Итак, я просто хочу иметь возможность изменять данные в списке для выбранного элемента. (Я проверяю список для пути текстуры, чтобы узнать, какой из них был изменен, потому что это статическое значение, которое не будет изменено во всей программе).

+0

Ваша последняя строка добавляет новый элемент в список – Alex

+4

Вы добавляете новую текстуру для * каждого * элемента в существующий список, который не имеет соответствующего 'Path'. Я бы подумал, что вам нужна логика: если * любой * элемент в списке имеет соответствующий «Путь», замените его. Если вы достигнете конца цикла for, не сделав этого, _then_ добавьте новый элемент (один раз). – CompuChip

+0

'Main.Textures.Add' добавит новый элемент в список. Поместите точку останова на условие 'if' и проверьте данные, над которыми вы работаете. Что-то заставляет вас попасть в состояние 'else'. –

ответ

2

Представьте, что ваш Textures коллекции имеет два Texture объектов в нем уже:

TextureA, Path = A 
TextureB, Path = B 

Теперь, скажем, вы пытаетесь добавить новую текстуру, TextureC с путем = B. Пройдем через вашу петлю и посмотрим, что получится:

Первая итерация: Textures[0].Path == texture.Path является ложным (потому что A! = B), поэтому мы выполняем инструкцию else и добавляем TextureC в коллекцию.

Так что теперь коллекция выглядит следующим образом:

TextureA, Path = A 
TextureB, Path = B 
TextureC, Path = B 

Вторая итерация: Условный утверждение верно (TextureB.Path == TextureC.Path), поэтому вы заменить этот пункт, теперь список выглядит следующим образом:

TextureA, Path = A; 
TextureC, Path = B; 
TextureC, Path = B 

Тогда есть третья итерация, но я думаю, что из этих двух должно быть ясно, где ваша ошибка. Что вам нужно сделать, так это отдельный поиск в списке существующего элемента из добавления элементов (поскольку каждый раз, когда вы пытаетесь заменить, ваш цикл будет добавлять одну копию текстуры, которую вы добавляете для каждого элемента в списке, t соответствует ему).

0

Свойство Count не является фиксированным в for -loop, если вы добавляете туда предметы., Он будет увеличиваться. Поэтому каждый раз, когда вы добавляете элемент, вы получаете еще одну итерацию, которую вы проверите позже. Это даже возможно получить OutOfMemoryException, так как вы добавляете текстуры бесконечно.

Вы могли бы пойти в обратное направлении:

for (int t = MainData.Textures.Count - 1; t >= 0; t--) 
{ 
     if (MainData.Textures[t].Path == texture.Path) 
      MainData.Textures[t] = texture; 
     else 
      MainData.Textures.Add(texture); 
} 
4

Просто сделать

var tex = Textures.FirstOrDefault(t => t.Path == texture.Path); 
if (tex != null) 
    tex = texture; 
else 
    Textures.Add(texture); 

Это более выразительным, на мой взгляд, и ведет себя, как вы хотите. Обратите внимание, что это только изменяет первый найденный, если таковой имеется.

Смежные вопросы