C # base class of a clone object

zhaozj2021-02-16  61

C # base class of a clone object

Amir Harel

Prompt in 2002, 12, 30

Summary: A class that implements the Icloneable interface.

Applications in: C #, .NET

Download Source Files - 1.27 KB

Introduction

Although the cloned subject in the real world is controversial, it is safe enough to use it in the .NET world, isn't it?

In order to achieve a class, how many times you have to implement the Icloneable interface, and write the same code for each time, or write a specific code for each class. Moreover, when your class joins a new field, it is often forgotten to update the cloning method of this new field. If I haven't mistaken, this time often brings annoying bugs.

This is the reason why my class is existing. With a small help of the reflex mechanism, I built an abstract class with the default behavior. Maybe you are asking yourself: What is the default behavior? So I am very happy to ask. Cloning's default behavior is to use the following rules to clone every field in the class:

Check if each field in the class supports IcloneAble interface

If a field does not support Icloneable interface, then this field will be processed in a regular manner. This means that if the field is a value type, then this value is copied; if the field is a reference type, the cloned field will point to the same object.

If this field supports the Icloneable interface, we will clone it using its own clone method.

If the field supports the Ienumerable interface, we need to check if he supports the ILIST or iDictionary interface. If support, then we iterate the column and view each item of the set to support the Icloneable interface.

how to use

Let your class support the iCloneable interface to do, put your class inherit your BaseObject class:

Public class myclass: baseObject

{

Public string mystr = "TEST";

Public int ID;

}

Public Class MyContainer: BaseObject

{

Public String Name = "Test2";

Public myclass [] myarray = new myclass [5];

Public class mycontainer ()

{

For (int i = 0; i <5; i )

{

THIS.MYARRAY [I] = new myclass ();

}

}

}

Now add the following code in the main method:

Static void main (string [] args)

{

Mycontainer con1 = new mycontainer ();

MyContainer Con2 = (MyContainer) Con1.clone ();

Con2.myArray [0] .id = 5;

}

When monitoring a CON2 instance, you will see the first item of the MyClass instance has changed to 5, and the CON1 instance has not changed. This way you will understand that the fields that join the iCloneable interface to the class will be cloned. Moreover, if the field supports the ILIST or iDictionary interface, the cloning method will detect this field and poll all items and try to clone them.

achieve

///

/// BaseObject class is an abstract class for inheritance.

/// Each class that is inherited by this class will automatically support the cloning method.

// / This class implements the Icloneable interface, and each object that is inherited from the object will be the same.

// / Support Icloneable interface.

/// Public Abstract Class BaseObject: iCloneable

{

///

/// Clone the object and return a reference to a cloned object

///

/// Reference New Cloning Objects

Public Object Clone ()

{

// First we establish an instance of the specified type

Object newobject = activator.createInstance (this.gettype ());

// We get the field array of new types of instances.

FieldInfo [] Fields = newobject.gettype (). Getfields ();

INT i = 0;

FOREACH (FieldInfo Fi in this.gettype (). getfields ())

{

// We determine if the field supports the Icloneable interface.

Type IclonType = fi.fieldType.

GetInterface ("iCloneable", true);

IclonType! = null)

{

// Acquire the Icloneable interface of the object.

Icloneable iClone = (iCloneable) FI.GetValue (this);

// We use the cloning method to set new values ​​to the fields.

Fields [i] .SetValue (NewObject, Iclone.clone ());

}

Else

{

// If the field is supported by the Icloneable interface, you can set it directly.

Fields [i] .SetValue (NewObject, Fi.GetValue (this));

}

// Now we check if the object supports the IEnumerable interface, if supported,

/ / We also need to enumerate all of its items and check if they support ILIST or iDictionary interfaces.

TYPE IENUMERABLETYPE = FI.FIELDTYPE.GETINTERFACE

("Iumerable", true);

IF (IEnumerablety! = NULL)

{

/ / Get the Ienumerable interface of this field

IENUMERABLE IENUM = (ienumerable) FI.GetValue (this);

// This version supports ILIST or iDictionary interface to iterate a collection. Type ilisttype = fields [i] .fieldtype.getInterface

("ILIST", TRUE;

Type idictype = fields [i] .fieldType.GetInterface

("IDictionary", true);

INT j = 0;

IF (ilisttype! = null)

{

// Get the ILIST interface.

IList List = (ilist) Fields [i] .GetValue (newObject);

Foreach (Object Obj Ienum)

{

/ / View whether the current item supports supporting the Icloneable interface.

IclonType = Obj.gettype ().

GetInterface ("iCloneable", true);

IclonType! = null)

{

// If you support the iCloneable interface,

// We use it to set the clone of objects in the list

Icloneable clone = (iCloneable) Obj; List [J] = Clone.clone ();

}

// Note: If the item in the list does not support the Icloneable interface, then

/ / The item in the cloning list will be the same as the original list

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

J ;

}

}

Else if (iDictype! = null)

{

// get the idictionary interface

IDictionary DIC = (iDictionary) fields [i].

GetValue (newobject);

J = 0;

Foreach (Dictionaryentry de in ienum)

{

/ / View whether the current item supports supporting the Icloneable interface.

IclonType = de.value.gettype ().

GetInterface ("iCloneable", true);

IclonType! = null)

{

Icloneable clone = (iCloneable) de.value;

DIC [de.key] = clone.clone ();

}

J ;

}

}

}

i ;

}

Return NewObject;

}

}

(Finish)

See the original text: base class for cloning an Object in C #

转载请注明原文地址:https://www.9cbs.com/read-22876.html

New Post(0)