您的位置:首页 > 理论基础 > 计算机网络

对象的深克隆-Clone【利用反射】转:http://www.codeproject.com/csharp/cloneimpl_class.asp

2007-10-30 19:35 801 查看
<PRE lang=cs id=pre2 style="MARGIN-TOP: 0px">/// <summary>

/// <B>BaseObject</B> class is an abstract class for you to derive from.

/// Every class that will be dirived from this class will support the

/// <B>Clone</B> method automaticly.

/// The class implements the interface <I>ICloneable</I> and there

/// for every object that will be derived

/// from this object will support the <I>ICloneable</I> interface as well.

/// </summary>

public abstract class BaseObject : ICloneable

{

/// <summary>

/// Clone the object, and returning a reference to a cloned object.

/// </summary>

/// <returns>Reference to the new cloned

/// object.</returns>

public object Clone()

{

//First we create an instance of this specific type.

object newObject = Activator.CreateInstance( this.GetType() );

//We get the array of fields for the new type instance.

FieldInfo[] fields = newObject.GetType().GetFields();

int i = 0;

foreach( FieldInfo fi in this.GetType().GetFields() )

{

//We query if the fiels support the ICloneable interface.

Type ICloneType = fi.FieldType.

GetInterface( "ICloneable" , true );

if( ICloneType != null )

{

//Getting the ICloneable interface from the object.

ICloneable IClone = (ICloneable)fi.GetValue(this);

//We use the clone method to set the new value to the field.

fields[i].SetValue( newObject , IClone.Clone() );

}

else

{

// If the field doesn't support the ICloneable

// interface then just set it.

fields[i].SetValue( newObject , fi.GetValue(this) );

}

//Now we check if the object support the

//IEnumerable interface, so if it does

//we need to enumerate all its items and check if

//they support the ICloneable interface.

Type IEnumerableType = fi.FieldType.GetInterface

( "IEnumerable" , true );

if( IEnumerableType != null )

{

//Get the IEnumerable interface from the field.

IEnumerable IEnum = (IEnumerable)fi.GetValue(this);

//This version support the IList and the

//IDictionary interfaces to iterate on collections.

Type IListType = fields[i].FieldType.GetInterface

( "IList" , true );

Type IDicType = fields[i].FieldType.GetInterface

( "IDictionary" , true );

int j = 0;

if( IListType != null )

{

//Getting the IList interface.

IList list = (IList)fields[i].GetValue(newObject);

foreach( object obj in IEnum )

{

//Checking to see if the current item

//support the ICloneable interface.

ICloneType = obj.GetType().

GetInterface( "ICloneable" , true );

if( ICloneType != null )

{

//If it does support the ICloneable interface,

//we use it to set the clone of

//the object in the list.

ICloneable clone = (ICloneable)obj;

list[j] = clone.Clone();

}

//NOTE: If the item in the list is not

//support the ICloneable interface then in the

//cloned list this item will be the same

//item as in the original list

//(as long as this type is a reference type).

j++;

}

}

else if( IDicType != null )

{

//Getting the dictionary interface.

IDictionary dic = (IDictionary)fields[i].

GetValue(newObject);

j = 0;

foreach( DictionaryEntry de in IEnum )

{

//Checking to see if the item

//support the ICloneable interface.

ICloneType = de.Value.GetType().

GetInterface( "ICloneable" , true );

if( ICloneType != null )

{

ICloneable clone = (ICloneable)de.Value;

dic[de.Key] = clone.Clone();

}

j++;

}

}

}

i++;

}

return newObject;

}

}

</PRE>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐