Valid C # item 27: Avoid icloneable

Source: Internet
Author: User

Valid C # item 27: Avoid icloneable

Icloneable sounds good: we can use it to support copying data types. However, our classes do not exist independently. Once we decide to support icloneable, all its derived classes also need to implement this interface. All internal members also need to support icloneable or other mechanisms for creating copies. Deep cloning often causes many problems. Theoretically, icloneable is used to solve these cloning problems: it can support shortest cloning or deep cloning. Create a new object in the shortest clone, and copy the original content to the object member. For the reference type, the new object is the same as the address referenced by the original object. Deep cloning also creates a new object and copies its members. All reference types are recursively cloned without referencing the original object member. For. Net built-in value types, such as int, there is no difference between the two clone methods. The exact type supported depends on our class. However, classes mixed with the latent cloning and deep cloning mechanisms may cause some errors. Once you fall into the trap of icloneable, it is very difficult to fall back. In general, try to create a class as simple as possible to avoid using icloneable. This is easy to use and implement.

Icloneable is not required for any value type that only contains built-in type members. Simply copying a value to a struct is more efficient than using clone. Clone () requires packing when the return value is returned. When using the return value, you need to unpack it.

What if the value type contains the reference type? The most common example is that a struct contains a string member:

Public struct errormessage
{
Private int errcode;
Private int details;
Private string MSG;
}

String is a special case because it is of an unchangeable type (see item7: prefer immutable atomic value types ). It does not cause the trouble of the general reference type. Because once the value of MSG changes, it indicates that it points to a new String object reference.

If the structure contains other reference types, the situation will be much more complicated. This is also common. When we use the built-in copy operation (simplest = Operator), we create a potential clone object, where the reference type members point to the same object as the members in the original struct. To create a deep copy, first determine whether the reference type in the structure supports deep copy.

We must be cautious when using icloneable, because we need to consider the situation of the derived class. Let's take a look at the following example:

Class basetype: icloneable
{
Private string _ label = "Class Name ";
Private int [] _ values = new int [10];


Icloneable member # region icloneable Member

Public object clone ()
{
Basetype rval = new basetype ();
Rval. _ label = _ label;
For (INT I = 0; I <_ values. length; I ++)
{
Rval. _ values [I] = _ values [I];
}
Return rval;
}

# Endregion
}

Class derived: basetype
{
Private double [] _ dvalues = new double [10];
}

// Call
Derived d = new derived ();
Derived D2 = D. Clone () as derived;
If (d2 = NULL)
{
Console. writeline ("null ");
}

After running, we will find that D2 is null. The derived class indeed calls the icloneable. Clone () method of the base class, but returns a base class object instead of a derived class. This is why D2 is null. Even if this problem is solved, _ dvalues In the derived class cannot be cloned successfully. We need to provide a hook function to make all the derived classes support cloning. In addition, the new member in the derived class must be of the value type or a clone reference type. This is a demanding requirement for a derived class. Supporting icloneable often brings us extra burden.

If you must support icloneable, you can create an abstract clone () method to implement all the derived classes. In this way, we also need to provide a method for the derived class to create a base class Object copy. In the following example, a protected copy constructor is defined:

Class basetype
{
Private string _ label;
Private int [] _ values;

Protected basetype ()
{
_ Label = "Class Name ";
_ Values = new int [10];
}

Protected basetype (basetype right)
{
_ Label = right. _ label;
_ Values = right. _ values. Clone () as int [];
}
}

Sealed class derived: basetype, icloneable
{
Private double [] _ dvalues = new double [10];

Public derived ()
{
_ Dvalues = new double [10];
}

Private derived (derived right)
: Base (right)
{
_ Dvalues = right. _ dvalues. Clone as int [];
}

Icloneable member # region icloneable Member

Public object clone ()
{
Derived rval = new derived (this );
Return rval;
}

# Endregion
}

In the above example, the basic class does not implement icloneable. It provides a protected constructor to allow the derived class to copy the base class members. For Derived classes declared as sealed, icloneable can be implemented as necessary. In this way, although the base class provides the necessary support for cloning, it does not require all the derived classes to be cloned.

Although icloneable has its advantages, it also causes a lot of trouble. Never allow the value type to support icloneable. Avoid using the icloneable interface unless necessary.

Translated from Objective C #: 50 specific ways to improve your C # by Bill Wagner

Back to directory
 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.