zoukankan      html  css  js  c++  java
  • 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关键字

  • 相关阅读:
    ThinkPhp框架分页查询和部分框架知识
    tp框架增删改
    WAMP中mysql服务突然无法启动 解决方法
    thinkphp框架 的 链接数据库和操作数据
    php 全局使用laravel的dd和dump
    给centos装图形界面 widowsx
    marquee标签的使用
    微信公众号开发入门教程
    laravel admin引入css js报错 https
    利用Croppie裁剪图片并后台保存
  • 原文地址:https://www.cnblogs.com/errornull/p/9782947.html
Copyright © 2011-2022 走看看