无法修改IEnumerable <t> </t>中对象的属性

时间:2010-11-30 15:20:35

标签: .net c#-4.0

我在修改IEnumerable集合中对象的属性时遇到问题。我将集合传递给另一个方法,以删除集合中实体的重复信息。这在方法中起作用,但是一旦方法完成执行并返回给调用者,则更改将丢失。但是,如果我将IEnumerable转换为列表,它将按预期工作。我唯一的猜测是,因为当我调用ToList时,它变成了一个具体的类型,并允许它工作,但这不应该是一个限制,对吧?

同样值得一提的是,这不是延迟执行的背景。 最终不成立,编译器重写了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);
        }    
    }

    ...
}

1 个答案:

答案 0 :(得分:3)

如果您的RetrieveTrackingFilters(proNumber)返回IQueryable,那么这会导致每次枚举时都会创建新对象:一次在RemoveDuplicateFilterData内(然后会丢失更改)有一次,当你稍后在RetrieveTrackingSummary做一些事情时(此时会提供一份新的,未经修改的副本)。

尝试将.ToList()更改为.AsEnumerable()。它应该仍然有效。