zoukankan      html  css  js  c++  java
  • 第6章类型和成员基础(CLR学习)

    类型的各种成员:

      1.常量 是指出数据值恒定不变的字符

      2.字段 表示只读或可读/可写的数据值。字段也可以是静态的;这种字段被认为是类型状态的一部分;字段也可以是实例(非静态);这种字段被认为是对象状态的一部分。

      3.实例构造器 是将新对象实例字段初始化为良好初始状态的特殊方法。

      4.类型构造器 是将类型的静态字段初始化为良好初始状态的特殊方法。

      5.方法 是更改或查询类型或对象状态的函数

      6.操作符重载 定义了当操作符作用于对象时,应该如何操作该对象。

      7.转换操作符 定义如何隐式或显示将对象从一种类型转型为另一种类型的方法。

      8.属性 允许用简单的.字段风格的语法设置或查询类型或对象的逻辑状态,同时保证状态不被破坏。

      9.事件 静态时间允许类型一个或多个静态或实例方法发送通知。实例(非静态)事件允许对象向一个或多个静态或实例方法发送通知。

      10.类型 类型可定义其他嵌套类型

      类型的可见性

        public类型不仅对定义程序集中所有代码可见,还对其他程序集中的代码可见。

        internal 类型则仅对定义程序集中所有代码可见

       什么事友元程序集;就是internal类型的程序可以在其他程序集可访问;生成程序集时,可用System.Runtime.CompilerServices命名空间中的InternalsVisibkeTo特性标明它可认为是“友元”的程序集。  

       1.创建一个项目控制台程序

        

        

      2 在项目ConsoleApp中添加对项目Utility的引用。

      3 将项目Utility中的类SomeInternalType访问级别设置为Internal。

      

    namespace Utility
    {
         
         internal class SomeInternalType
        {
             public override string ToString()
             {
                 return string.Format("{0}","开始");;
             }
        }
    }

      4 现在在ConsoleApp项目中是肯定不能访问到类SomeInternalType的,如果想让类Program可以访问类SomeInternalType,必须将项目ConsoleApp的程序集添加为项目Utility程序集的友元程序集。添加友元程序集我们要使用InternalIsVisibleTo特性,使用该特性需要添加命名空间

        using System.Runtime.CompilerServices。

      5 在SomeInternalType类中使用InternalIsVisibleTo特性将程序集ConsoleApp添加为友元程序集。

    using System.Runtime.CompilerServices;
    
    [assembly: InternalsVisibleTo("ConsoleApp")]
    namespace Utility
    {
         
         internal class SomeInternalType
        {
             public override string ToString()
             {
                 return string.Format("{0}","开始");;
             }
        }
    }
    

      6 InternalIsVisibleTo特性也可以添加到AssemblyInfo.cs中。

    7 现在在项目Utility的类SomeInternalType中就可以访问ConsoleApp项目的类Program了。

     合理使用类型的可见性和成员的可访问性

      三个方面:版本控制,性能,安全性和可预测性

     定义类时遵循的原则

      1.定义类时,除非确定要将其作为基类,并允许派生类对它进行特化,否则总是显示地指定为Sealed类型。如果真要定义一个可由其它类继承的类,同时不希望允许特化,那么会重写并密封继承的所有虚方法。

      2.类的内部,将数据字段定义为私有"private"。

      3.在类的内部,将方法,属性和事件定义的顺序为:优先考虑private和非虚,再考虑public,再到protected和internal,最后定义为virtual;因为虚成员会放弃许多控制,丧失独立性,变得彻底依赖于派生类的正确行为。

      4.oop有一条古老的格言,大意是当事情变得过于复杂的时,就搞更多的类型出来。当算法的实现开始变得复杂时,定义一些辅助(例如:扩展类等)类型来封装独立的功能。

    对类进行版本控制时的虚方法的处理

      1,创建两个类基类A和派生类B 如果两个类中都相同的方法和虚拟方法 就需要在派生类方法前面加上new关键字,new关键字告诉编译器生成的元数据,让CLR知道A类型的方法应被视为A类型引入的心函数。

      

    namespace CompayA
    {
        public  class Phone
        {
            public void Dial()
            {
                Console.WriteLine("Phone.Dial");
                EstablishConnection();
            }
    
            public virtual void EstablishConnection()
            {
                Console.WriteLine("Phone.EstablishConnection");
            }
        }
    }
    

      

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace CompayB
    {
        public  class BeeterPhone:CompayA.Phone
        {
            public new void Dial()
            {
                Console.WriteLine("BeeterPhone.Dial");
                EstablishConnection();
                base.Dial();
            }
    
            public new virtual  void EstablishConnection()
            {
                Console.WriteLine("BeeterPhone.EstablishConnection");
            }
        }
    }
    
       class Program 
        {
            static void Main(string[] args)
            {
             
               //SomeInternalType c=new SomeInternalType();
               // Console.WriteLine(c);
                CompayB.BeeterPhone  phone=new BeeterPhone();
                phone.Dial();
                Console.ReadKey();
            }
            
            
        }
    

      

    程序执行的结果为:

        BeeterPhone.Dial

        BeeterPhone.EstablishConnection

        Phone.Dial

        Phone.EstablishConnection

    2.如果派生类B把虚拟方法的new关键字去掉,并把Virtual改成override话执行的结果就不一样了;

      

    namespace CompayB
    {
        public  class BeeterPhone:CompayA.Phone
        {
            public new void Dial()
            {
                Console.WriteLine("BeeterPhone.Dial");
                EstablishConnection();
                base.Dial();
            }
    
            public override  void EstablishConnection()
            {
                Console.WriteLine("BeeterPhone.EstablishConnection");
            }
        }
    }
    

     执行的结果:   

      BeeterPhone.Dial
      BeeterPhone.EstablishConnection
      Phone.Dial
      BeeterPhone.EstablishConnection
  • 相关阅读:
    Unrecognized attribute 'targetFramework'.错误解决
    [译]Razor内幕之模板
    [译]Razor内幕之解析
    Java下载中文乱码问题解决方法
    获取矩形中心点与矩形外某点连线和矩形交点的算法
    做产品开发的感想
    [译]Razor内幕之表达式
    Could not find the main class. Program will exit.
    基于SAML的单点登录.NET代理端实现方案
    Linux内核虚拟内存的管理结构说明
  • 原文地址:https://www.cnblogs.com/jzhou/p/4895052.html
Copyright © 2011-2022 走看看