iservice list方法_扩展IList对象,实现深拷贝扩展方法

应用场景

对一个集合进行深拷贝复制,实现的方法有不少,现举一个常规实现方案:例如已有一个List someList

List newList = new List();

foreach(var item in someList)

{

T t = new T();

//此处的属性如果是引用类型,还需要考虑该类型的深拷贝实现

t.P1 = item.P1;

t.P2 = item.P2;

...

newList.Add(t);

}

如果类似的需求不止一个,那我们就要反复书写类似的代码,这显然不符合代码重用的原则。

思路

首先想到的应该是扩展方法,并且是基于泛型的扩展方法,这个简单,上代码:

public static IList Clone(this IList source)

{

IList newList = new List(source.Count);

foreach (var item in source)

{

newList.Add(..);

}

return newList;

}

这个add方法里还是要new一个T对象,并且挨个给属性赋值,那岂不是也很麻烦,这时候肯定有同学想到了反射,对,使用反射可以解决这个问题,但我认为还不是很理想。

第二次思考。。。对了,微软不是已经为我们提供了一个接口叫ICloneable的么?我们应该为T加上约束,修改代码如下:

public static IList Clone(this IList source)

where T : ICloneable

{

IList newList = new List(source.Count);

foreach (var item in source)

{

newList.Add((T)((ICloneable)item.Clone()));

}

return newList;

}

现在看上去还不错了,基本思路已经成型,在调用的时候可以这样使用: newList = someList.Clone();

当然,别忘了给你的T加上ICloneable接口,并实现Clone方法,实现Clone的方法有很多,个人建议如下:

public object Clone()

{

MemoryStream stream = new MemoryStream();

BinaryFormatter formatter = new BinaryFormatter();

formatter.Serialize(stream, this);

stream.Position = 0;

var obj = formatter.Deserialize(stream) as Class;

return obj;

}

使用序列化的方式进行对象的复制,这样做的前提是你的Class需要被标记为Serializable。

使用EF时碰到的实际案例

例如一个Entity有很多关联的实体(主子表),现在需要复制原始记录作为一份全新的记录,包括所有的子表,如果采用常规方法,做起来是会很繁琐的,需要挨个遍历子表集合,并new一个全新的实体对象,再挨个执行AddObject,如果采用上面的方案,代码如下:

//子表集合var resList = this.ResourcePlanService.GetList(t => t.QuoteID == quoteId).ToList();

ForeachCopy(resList, this.ResourcePlanService);

private void ForeachCopy(IList list, TService service)

where TService : IService

where TModel : ICloneable

{

list.Clone().ForEach( t => service.Add(t) );

}

这样代码就精简了很多,对原来的改动也相对较小,只需要把TModel的基类EntityObjectBase实现ICloneable接口,并实现Clone方法即可,需要注意的是,如果EF采用DB First方式,则需要在Clone方法里面把EntityKey设置为null,否则,在调用AddObject的时候,ObjectManagement会抛出异常。

总结

优点:代码简单、复用度高

缺点:需要修改类对象以继承ICloneable接口,如果没有基类的话,也是一个很麻烦的问题,并且类对象需要被标记为Serializable

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值