在Actions中执行Actions以进行收集而不创建新集合

时间:2016-05-29 09:10:25

标签: c# linq generics collections lambda

我有对象集合,其中每个对象包含其他对象集合。所有我想以某种方式修改我的原始对象集合,不应分配额外的内存。一切都应该在记忆中发生。

我正在寻找一些模板化的Action或Func,以便通过声明和功能方法的混合,不会形成新的集合,并且在内存中我的原始集合也会被修改。

以下是集合的层次结构

public class ConsignmentAddress
{
    public int ConsignmentAddressId { get; set; }
    public int AddressTypeId { get; set; }
    public string Street { get; set; }
    public string Town { get; set; }
    public string ZipCode { get; set; }
    public int ConsignmentId { get; set; }


}
public class ConsignmentLine
{
    public int ConsignmentLineId { get; set; }
    public int PackagingId { get; set; }
    public double Amount { get; set; }
    public double Weight { get; set; }
    public int ConsignmentId { get; set; }
    public int? PackagingAidId { get; set; }


}
public class PackagingAid
{
    public int PackagingAidId { get; set; }
    public int ConsignmentId { get; set; }
    public int PackagingId { get; set; }
    public double Quantity { get; set; }
}
public class Consignment
{
    public int ConsignmentId { get; set; }
    public int ClientSubsidiaryId { get; set; }
    public int ForwarderId { get; set; }
    public int Sourcepaty { get; set; }
    public int ParentId { get; set; }
    public int ProductId { get; set; }

    public ICollection<PackagingAid> PackagingAids { get; set; }
    public ICollection<ConsignmentLine> ConsignmentLines { get; set; }
    public ICollection<ConsignmentAddress> ConsignmentAddresses { get; set; }

    public Consignment()
    {
        PackagingAids = new List<PackagingAid>();
        ConsignmentLines = new List<ConsignmentLine>();
        ConsignmentAddresses = new List<ConsignmentAddress>();
    }        
}

我的目的是编写通用扩展方法,该方法应该对我上面提到的层次结构中的所有类型的对象进行操作。

public static class ConsignmentExtension
{
    public static T Set<T>(this T input, Action<T> updater)
    {
        updater(input);
        return input;
    }
}

我的客户代码首先获得列表中10000个对象的列表,并重置少量属性(寄售,寄售地址为相应的寄售,相应寄售的寄售线和相应寄售的包装)

我写的Foreach方法运行良好但我希望对同一个集合采用模板化和高效的方法。

consignments.ForEach(cons => 
        {
                                        cons.ConsignmentId = -1;
                                        cons.ConsignmentAddresses.ToList().ForEach(address => 
                                        {
                                            address.ConsignmentId = -1;
                                            address.ConsignmentAddressId = -1;
                                        });
                                        cons.ConsignmentLines.ToList().ForEach(line => 
                                        {
                                            line.ConsignmentId = -1;
                                            line.ConsignmentLineId = -1;
                                            line.PackagingAidId = -1;
                                        });
                                        cons.PackagingAids.ToList().ForEach(aid => 
                                        {
                                            aid.ConsignmentId = -1;
                                            aid.PackagingAidId = -1;
                                        });                                             
        });

但我正在寻找像陈述式风格的东西。

var updatedConsignments = from consignment in consignments
                                  select consignment.Set<Consignment>(con =>
                                  {
                                      con.ConsignmentId = -1;
                                      con.ConsignmentAddresses.Set<dynamic>(address => { address.ConsignmentId = -1; address.ConsignmentAddressId = -1; });
                                      con.ConsignmentLines.Set<dynamic>(line => { line.PackagingAidId = -1; line.ConsignmentId = -1;line.ConsignmentLineId = -1; });
                                      con.PackagingAids.Set<dynamic>(aid => { aid.ConsignmentId = -1; aid.PackagingAidId = -1; });
                                  });

这有可能吗? 提前谢谢。

1 个答案:

答案 0 :(得分:0)

这可以写成

public static class ConsignmentExtension
{
   public static IEnumerable<dynamic> SetEach(this IEnumerable<dynamic> input, Action<dynamic> updater)
   {
       foreach (var item in input)
       {
           updater(item);
       }

       return input;
}

}

用法:

           var addresses = new [] 
            {
                new ConsignmentAddress()
            };

            addresses.SetEach(a => a.ConsignmentId = -1);

            var packages = new []
            {
                new PackagingAid()
            };
            packages.SetEach(p => p.PackagingAidId = -1);