zoukankan      html  css  js  c++  java
  • Effective C# 学习笔记(三十三) 只在更新基类时,使用new关键字

    对于new关键字在修饰方法的使用我们要小心,因为它并不是像看上去那样会把父类nonVirtual的方法,转为virtual方法。

    首先,看一个例子:

    object c = MakeObject();

    // Call through MyClass reference:

    MyClass cl = c as MyClass;

    cl.MagicMethod();

    // Call through MyOtherClass reference:

    MyOtherClass cl2 = c as MyOtherClass;

    cl2.MagicMethod();

    When the new modifier is involved, that just isn’t the case:

    public class MyClass

    {

    public void MagicMethod()

    {

    Console.WriteLine("MyClass.MagicMethod");

    }

    }

    public class MyOtherClass : MyClass

    {

    // Redefine MagicMethod for this class.

    public new void MagicMethod()

    {

    Console.WriteLine("MyOtherClass.MagicMethod");

    }

    }

    上面的代码经常会让人误以为MyOtherClass的实现会覆盖掉MyClassMagicMethod方法的实现,但事实上两个类的方法会在对象的引用不同时调用不同的方法。如:

    上例中奖 cl2对象再次转换为MyClass对象后,其又会执行MyClassMagicMethod方法。这样就会给人以误解,同样一个对象,只是因为引用类型不同则同样的方法的执行逻辑就不一致。

     

    其实new关键字的适用场景一般只有在父类的新方法与子类的已有方法重名时起到覆盖父类重名方法的作用。

    例如下面代码中MyWidget继承自BaseWidget,而MyWidget有一个方法NormalizeValues,该类已被其类的消费者使用。这时父类发布了新版本,添加了新feature但是其添加了一个同名的NormalizeValues方法,所以你需要使用new关键字来覆盖合并父类的逻辑。

    public class MyWidget : BaseWidget

    {

    public void new NormalizeValues()

    {

    // details elided.

    // Call the base class only if (by luck)

    // the new method does the same operation.

    base.NormalizeValues(); //别忘了调用父类的逻辑

    }

    }

     

    若你能修改父类的代码,还是最好把父类的方法名改为它名,因为你的子类可能已被许多用户使用了,所以为了最小化工作量,还是让父类新增方法不要与子类的旧方法冲突的好。还有用户可能还需直接使用父类的方法,若你不能修改父类的方法名称,你可能必须修改你子类的方法了,但是长痛不如短痛,这样你以后也不必为这些重名的方法进行额外的维护了,尤其是在需求多变的情况下。

  • 相关阅读:
    Vue 冷知识(一)
    Google Chrome 谷歌浏览器 调试被坑之路
    全选、全不选、反选
    赋值运算符
    JS 数组的常用方法归纳之不改变原数组和其他
    CSS控制文字,超出部分显示省略号
    火狐浏览器解决跨域问题
    JS 数组的常用方法详解归纳之改变原数组方法
    vue项目 多文件上传并显示在页面上
    二叉搜索树操作
  • 原文地址:https://www.cnblogs.com/haokaibo/p/2109386.html
Copyright © 2011-2022 走看看