• CLR via C#学习笔记-第八章-分部方法


    8.7 分部方法

    重写基类的虚方法

    使用继承基类让子类重写基类虚方法的做法存在很多问题,如下所示代码。

    //工具生成的代码,存储在某个代码文件中
    internal class Base
    {
        private String m_name;    protected virtual void OnNameChanging(String value){}
        public String Name
        {
            get{return m_name;}
            set{
                OnNameChanging(value.ToUpper());
                m_name=value;
            }
        }
    }
    //开发人员生成的代码。存储在另一个源代码文件中
    internal class Derived:Base
    {
        protected override void OnNameChanging(string value)
        {
            if(String.IsNullOrEmpty(value))
                throw new ArgumentNullException("value");
        }
    }

    1.类型必须是非密封的,也不能用于值类型,因为值类型是隐式密封的。此外不能用于静态方法,因为静态方法不能重写。

    2.效率问题。定义一个类只为了重写一个方法,会浪费少量系统资源。即使不想重写某个方法,基类代码仍需调用一个什么都不做直接就返回的虚方法。

    分布方法的实现

    利用C#的分部方法就可以解决以上问题的同时覆盖类的行为。

    //工具生成的代码,存储在某个代码文件中
    internal sealed partial class Base
    {
        private String m_name;
        partial virtual void OnNameChanging(String value){}
        public String Name
        {
            get{return m_name;}
            set{
                OnNameChanging(value.ToUpper());
                m_name=value;
            }
        }
    }
    //开发人员生成的代码。存储在另一个源代码文件中
    internal sealed partial class Base
    {
        partial void OnNameChanging(string value)
        {
            if(String.IsNullOrEmpty(value))
                throw new ArgumentNullException("value");
        }
    }

    1.类现在密封,事实上类可以是静态类甚至可以是值类型。

    2.详细介绍partial关键字见第六章6.5节。

    好处是,可以重新运行工具,在新的源代码文件中生成新的代码,但你自己的代码是存储在一个单独的文件中,不会受到影响。

    性能提升

    此外,分部方法还提供了另一个巨大的提升。如果不想修改工具生成的类型的行为,那么根本不需要提供自己的源代码文件。

    如果只是对工具进行编译,编译器会改变生成的IL代码和元数据,使工具生成的代码变成这样。

    //如果没有分布方法的实现
    //工具生成的代码在逻辑上等价于以下代码
    internal class Base
    {
        private String m_name;
        public String Name
        {
            get{return m_name;}
            set{
                OnNameChanging(value.ToUpper());
                m_name=value;
            }
        }
    }

    也就是说没有实现分部方法,编译器不会生产任何代表分部方法的元数据、IL指令。

    规则和原则

    1.他们只能在分部类或者结构声明。

    2.分部方法返回的始终是void,任何参数都不能用out修饰符来标记。

    3.分部方法的声明和实现必须具有完全一致的签名。

    4.分部方法总是被视为private方法。但C#编译器禁止在分布方法声明之前天机private关键字

  • 相关阅读:
    (译).NET4.X并行任务Task需要释放吗?
    微软面向高并发应用而推出的新程序库——TPL Dataflow
    C# 5.0 Async函数的提示和技巧
    内存泄露——文章
    AJAX POST请求中参数以form data和request payload形式在php中的获取方式
    NodeJS中间层搭建
    HTML5上传预览
    laravel 图片上传 ajax 方式
    抽奖程序
    IText 生成页脚页码
  • 原文地址:https://www.cnblogs.com/errornull/p/9782947.html
Copyright © 2020-2023  润新知