第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
posted on 2015-10-20 15:48  紫色的冰  阅读(166)  评论(0编辑  收藏  举报