using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Text;
using
System.Reflection;
namespace
Kevin.CommonFunction.Clone
{
///
<summary>
///
复制元素的容器
///
</summary>
///
<remarks>
///
执行批量的复制,默认只复制对象的值类型,引用关系保留
///
</remarks>
public
class
CopyContainer
{
#region
属性
///
<summary>
///
上下文环境参数
///
</summary>
private
Dictionary
<
string
,
object
>
mContextParams;
///
<summary>
///
等待被复制的对象
///
</summary>
private
List
<
object
>
mWaitToCopiedItems
=
new
List
<
object
>
();
///
<summary>
///
被复制对象-新对象的索引关系
///
</summary>
private
Dictionary
<
object
,
object
>
mItemIndexs
=
new
Dictionary
<
object
,
object
>
();
///
<summary>
///
构造函数的缓存
///
</summary>
private
Dictionary
<
Type, ConstructorInfo
>
mConstcCache
=
new
Dictionary
<
Type, ConstructorInfo
>
();
///
<summary>
///
字段的缓存
///
</summary>
private
Dictionary
<
Type, List
<
FieldInfo
>>
mFieldInfoCache
=
new
Dictionary
<
Type, List
<
FieldInfo
>>
();
///
<summary>
///
复制后的新对象
///
</summary>
private
List
<
object
>
mNewItems
=
new
List
<
object
>
();
#endregion
#region
构造函数
///
<summary>
///
///
</summary>
public
CopyContainer()
{
}
#endregion
#region
方法
///
<summary>
///
添加等待被复制的对象
///
</summary>
///
<param name="waitCopiedItem">
需要复制的对象
</param>
public
void
AddToWaitCopiedItems(
object
waitCopiedItem)
{
if
(waitCopiedItem
!=
null
&&
!
mWaitToCopiedItems.Contains(waitCopiedItem))
{
this
.mWaitToCopiedItems.Add(waitCopiedItem);
}
}
///
<summary>
///
添加环境参数
///
</summary>
///
<param name="key">
环境中的唯一主键
</param>
///
<param name="contextParam">
环境参数
</param>
public
void
AddToContextParams(
string
key,
object
contextParam)
{
if
(mContextParams
==
null
)
{
mContextParams
=
new
Dictionary
<
string
,
object
>
();
}
this
.mContextParams.Add(key, contextParam);
}
///
<summary>
///
复制对象
///
</summary>
///
<returns>
所有复制后的对象列表
</returns>
public
List
<
object
>
Clone()
{
if
(
this
.mWaitToCopiedItems
==
null
)
{
return
null
;
}
foreach
(
object
obj
in
this
.mWaitToCopiedItems)
{
object
newObj
=
CopyToNewObj(obj);
mItemIndexs.Add(obj, newObj);
mNewItems.Add(newObj);
}
foreach
(
object
newObj
in
mNewItems)
{
ICopyReference copiedObj
=
newObj
as
ICopyReference;
if
(copiedObj
!=
null
)
{
copiedObj.SetReference(
this
.mContextParams,
this
.mItemIndexs);
}
}
return
this
.mNewItems;
}
///
<summary>
///
复制对象
///
</summary>
///
<param name="copeidItem">
被复制的对象
</param>
///
<returns>
复制后的对象
</returns>
private
object
CopyToNewObj(
object
copeidItem)
{
Type copiedType
=
copeidItem.GetType();
ConstructorInfo constc
=
this
.GetConstructor(copiedType);
List
<
FieldInfo
>
fields
=
this
.GetFieldInfos(copiedType);
object
newObj
=
constc.Invoke(
null
);
foreach
(FieldInfo field
in
fields)
{
object
copiedValue
=
field.GetValue(copeidItem);
field.SetValue(newObj, copiedValue);
}
return
newObj;
}
///
<summary>
///
获取构造函数
///
</summary>
///
<param name="copiedType">
被复制对象的类型
</param>
///
<returns>
构造函数
</returns>
private
ConstructorInfo GetConstructor(Type copiedType)
{
ConstructorInfo copiedConstc
=
null
;
if
(
this
.mConstcCache.ContainsKey(copiedType))
{
copiedConstc
=
this
.mConstcCache[copiedType];
}
//
该构造函数未加入缓存
else
{
ConstructorInfo[] constructors
=
copiedType.GetConstructors(BindingFlags.NonPublic
|
BindingFlags.Instance
|
BindingFlags.Public);
//
循环所有构造函数
foreach
(ConstructorInfo constc
in
constructors)
{
ParameterInfo[] paramsInConst
=
constc.GetParameters();
if
(paramsInConst.Length
==
0
)
{
copiedConstc
=
constc;
break
;
}
}
if
(copiedConstc
==
null
)
{
throw
new
Exception(
string
.Format(
"
类 '{0}' 缺少无参的构造函数
"
, copiedType.FullName));
}
this
.mConstcCache.Add(copiedType, copiedConstc);
}
return
copiedConstc;
}
///
<summary>
///
获取字段
///
</summary>
///
<param name="copiedType">
被复制对象的字段
</param>
///
<returns>
字段
</returns>
private
List
<
FieldInfo
>
GetFieldInfos(Type copiedType)
{
List
<
FieldInfo
>
fields
=
null
;
if
(
this
.mFieldInfoCache.ContainsKey(copiedType))
{
fields
=
this
.mFieldInfoCache[copiedType];
}
//
该字段未加入缓存
else
{
fields
=
new
List
<
FieldInfo
>
();
FieldInfo[] fieldsInCT
=
copiedType.GetFields(BindingFlags.Public
|
BindingFlags.NonPublic
|
BindingFlags.Instance);
foreach
(FieldInfo fieldItem
in
fieldsInCT)
{
//
过滤带有KeepFixedValueAttribute自定义属性的字段
if
(fieldItem.GetCustomAttributes(
typeof
(KeepFixedValueAttribute),
true
).Length
==
0
)
{
fields.Add(fieldItem);
}
}
this
.mFieldInfoCache.Add(copiedType, fields);
}
return
fields;
}
#endregion
}
}