2010-11-30 3 views
2

У меня возникла проблема с внесением изменений в свойства объектов в коллекции IEnumerable. Я передаю коллекцию другому методу удаления дублированной информации по всем объектам коллекции. Это работает в методе, но как только метод выполняется и возвращается вызывающему, изменения теряются. Однако, если я конвертирую IEnumerable в список, он работает так, как ожидалось. Мое единственное предположение заключается в том, что, когда я вызываю ToList, он становится конкретным типом и позволяет ему работать, но это не должно быть ограничением, правильно?Невозможно изменить свойства объектов в IEnumerable <T>

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

Это урезана код:

public IEnumerable<TrackingFilter> RetrieveTrackingFilters(string proNumber) 
{ 
    var trackingFilters = new EntityCollection<TrackingOverviewFilterEntity>(new TrackingOverviewFilterEntityFactory()); 

    var filter = new RelationPredicateBucket(); 
    filter.Relations.Add(TrackingOverviewFilterEntity.Relations.TrackingOverviewEntityUsingTrackingOverviewId); 
    filter.PredicateExpression.Add(TrackingOverviewFields.ProNumber == proNumber); 

    DataAccessAdapterFactory.Instance().FetchEntityCollection(trackingFilters, filter); 

    return BuildTrackingFilterColl(trackingFilters); //Just news up a DTO object and populates it 
} 

public TrackingSummaryViewModel RetrieveTrackingSummary(string proNumber) 
{ 
    ... 
    var trackingFilters = this._TrackingOverviewDataController.RetrieveTrackingFilters(proNumber).ToList(); //Works 
    //var trackingFilters = this._TrackingOverviewDataController.RetrieveTrackingFilters(proNumber); //Doesn't work 

    RemoveDuplicateFilterData(trackingFilters); //If I don't do a ToList() then the changes that occur in this method call do not persist 
    ... 
} 

private static void RemoveDuplicateFilterData(IEnumerable<TrackingFilter> filters) 
{ 
    var valuePairs = new Dictionary<string, IList<object>>(); 

    foreach (var filter in filters) 
    { 
     if (valuePairs.ContainsKey("comments") && valuePairs["comments"].Contains(filter.Comments)) 
     { 
      filter.Comments = string.Empty; 
     } 
     else if (!string.IsNullOrWhiteSpace(filter.Comments)) 
     { 
      if (!valuePairs.ContainsKey("comments")) 
      { 
       valuePairs.Add("comments", new List<object>()); 
      } 

      valuePairs["comments"].Add(filter.Comments); 
     }  
    } 

    ... 
} 
+2

'.ToList()' не относится к списку, это метод расширения, который создает новый список со значениями из IEnumerable. Результатом является не старая структура, занесенная в список, а новая структура с теми же элементами, что и старые. –

+0

@albin sunnanbo, извините, вы правы, я использовал неправильную формулировку. Я действительно это знал. – joshlrogers

+0

Является ли ваш тип структурой? –

ответ

3

Если ваш RetrieveTrackingFilters(proNumber) возвращает IQueryable, то это будет создавать новые объекты каждый раз, когда вы его перечисляете: один раз в пределах RemoveDuplicateFilterData (изменения там будут потеряны) и один раз, когда вы что-то с ним сделаете позже в RetrieveTrackingSummary (на данном этапе будет предоставлена ​​новая, нетронутая копия).

Попробуйте изменить .ToList() на .AsEnumerable(). Он должен по-прежнему работать одинаково.

+0

Первым методом в моей паре кода является RetrieveTrackingFilters, и он возвращает IEnumerable . – joshlrogers

+0

@joshlrogers, IQueryable реализует IEnumerable , поэтому IQueryable может быть «скрыт» внутри IEnumerable. –

+0

@joshlrogers, проверьте тип времени выполнения в отладчике –

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