Valid C # item 29: use the new modifier only when base class updates mandate it

Source: Internet
Author: User

Valid C # item 29: use the new modifier only when base class updates mandate it

When we need to redefine a non-Virtual Member of the base class, we can use the new modifier, but this does not mean we should do this. This type of redefinition may cause behavioral ambiguity. When most programmers see the following code at both ends, they will think that if these two classes are inherited, their behavior should be the same:

Object C = makeobject ();

Myclass C1 = C as myclass;
C1.magicmethod ();

Mytherclass C2 = C as mytherclass;
C2.magicmethod ();

However, if the new clause is used for redefinition, the result may not be as follows:

Public class myclass
{
Public void magicmethod ()
{
}
}

Public class mytherclass: myclass
{
Public new void magicmethod ()
{
}
}

This situation often causes headaches for many developers. If you call the same method of the same object, we expect the execution results to be the same. But in fact, although the names are the same, they call different functions, which is very bad. It destroys uniqueness. The behavior of the mytherclass object is not what we expect. Using the new modifier allows us to add a completely different method to the class, which is different from rewriting the virtual method in the base class.

Non-virtual methods are static. These methods call the same function no matter where the code is located. Different versions of this method are not found in its derived classes during runtime. The virtual method is dynamically determined. Different versions of the method are called for different types during runtime.

We should avoid using new to redefine non-virtual methods. Otherwise, we need to declare all methods in the base class as virtual. The designer adds a behavior convention to the class by defining these virtual methods. Its Derived classes can all achieve their own different implementation needs through this virtual method. Each virtual method defines the behavior that the derived class may need to change. The "Default virtual method" design assumes that all the methods in the base class are virtual, and the derived class can modify all the behaviors in the base class. This usually means that you have not seriously considered the branch relationship between the behaviors of the derived classes. We should spend more time thinking about the methods and attributes in the derived classes that require polymorphism, and simply set these required methods and attributes to virtual ones. We should not consider this as a limitation on users. Instead, it serves as an entry to guide the user to customize the behavior.

In only one case, we should use the new modifier: We updated a new version of the base class, which contains methods with the same name as our original type. In the following example, we create a mywidget class and use the basewidget class defined by other class libraries as the base class:

Public class mywidget: basewidget
{
Public void dowidgetthings ()
{
}
}

We have completed this class and delivered it to users. Then we found that the basewidget company released a new version of the basewidget class. Enthusiasm for new features allows us to immediately try to use the new base class to build the mywidget class. However, it failed, because we found that their own dowidgetthings method was added to the basewidget.

Public class basewidget
{
Public void dowidgetthings ()
{
}
}

The problem occurs. Our new base class secretly provides a method with the same name as our type. We have two ways to solve this problem. First, change the name of the dowidgetthings method in our class:

Public class mywidget: basewidget
{
Public void domywidgetthings ()
{
}
}

The second is to use the new modifier:

Public class mywidget: basewidget
{
Public new void dowidgetthings ()
{
}
}

If you can obtain the client code of all the mywidget classes used, you should select the method to change the name. However, if we have released the mywidget class, this modification will force all our users to modify their code. If the publishing scope is large, the cost for such modifications is too high. The new operator helps us solve this problem. All clients can continue using the dowidgetthings () method without making any changes. No user will use basewidget. dowidgetthings () because they do not know that the base class has such a method. The new operator hides conflicting members when upgrading the base class version.

Of course, some users may need to use the basewidget. dowidgetthings () method after a period of time. In this way, we return to the original problem: the two methods have the same name but different behavior. Considering that the use of the new modifier produces long-term semantic differences, although it is difficult to change the method name, this approach is often more appropriate.

Be careful when using the new modifier. Improper use may cause ambiguity of method calls. It can be used for special processing only when the base class of the upgrade has a name conflict. Even so, use it with caution. Do not use the new modifier in other cases.

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.