首页 > 代码库 > .net技术深入

.net技术深入

  程序集(Assembly),可以看做是一堆相关类打一个包,相当于java中的jar包(*)。打包的目的:程序中只引用必须的程序集,减小程序的尺寸;一些程序集内部的类不想让其他程序集调用。

  我们调用的类都是位于各个程序集中,如果调用的类在没有引用的程序集中,则需要添加对那个程序集的引用,比如ConfigurationManager。
  访问级别:private、public、protected
  类如果不标注访问级别则是internal级别,也就是只能在程序集内部访问,如果想跨程序集访问,则需要public或者使用InternalsVisibleTo(*)

  还可以编写自己的程序集,新建→类库,使用这个类库的程序只要引用生成的dll即可,如果是引用同一个解决方案中类库,则最好添加项目引用。项目不能循环引用,就是A引用B,B又引用A。
  exe、dll都是程序集,只不过exe有入口而已,exe也可以被添加引用。dll不一定是程序集(VC写的dll就不是程序集),程序集不一定是dll(.net写的EXE也是程序集)。
  访问级别约束:子类访问级别不能比父类高。
  声明委托的方式:delegate 返回值类型 委托类型名(参数)。比如delegate void StringProcess(string s);注意这里的除了前面的delegate,剩下部分和声明一个函数一样,但是StringProcess不是函数名,而是委托类型名
  声明的委托是一种类型,就像int、Person一样,如果要用的话还要声明委托类型的变量,声明委托类型变量的方式:StringProcess f1;
 将委托类型变量指向函数 StringProcess sp = new StringProcess(SayHello),这样就可以像调用普通函数一样把sp当成函数用了。委托可以看做是函数的指针。整数可以用整数变量指向它,对象可以用对象变量指向它,函数也可以用委托变量指向它。和直接调用函数的区别:用委托就可以指向任意的函数,哪怕是之前没定义的都可以,而不使用受限于那几种。
  将委托类型变量指向函数还可以简化成StringProcess sp = SayHello,编译器帮我们进行了new。但是不能sp=PrintIt(),因为这样就成了“执行PrintIt函数,并且将sp指向PrintIt的返回值”。

  delegate void ProcessWordDelegate(string s)
  ProcessWordDelegate d = new ProcessWordDelegate(SayHello)+new ProcessWordDelegate(ToLower)
  组合的委托必须是同一个类型,相当于创建了一个按照组合的顺序依次调用的新委托对象。
  d+=SayHello,为委托增加一个方法,不要感觉奇怪,因为它就是d=d+ SayHello
  d-=SayHello,将方法从委托中移除。

  事件语法:event ProcessWordDelegate{add{...},remove{...}}add、remove和属性、索引一样最终都编译成两个方法。如果是简单的增加委托,没有特殊的判断逻辑可以简写,一般情况下都是简写。
  加了event关键字实现事件机制的好处:用了event事件,不可以修改事件已经注册的值;不可以冒充进行事件通知了。event会自动生成一个private delegate变量和两个函数: add和remove.
  public event MyDelegate OnEvent;
  内部实现是(示例性)
  private MyDelegate OnEvent;
  public void Add(MyDelegate d)
  {
  OnEvent+=d;
  }
  public void Remove(yDelegate d)
  {
  OnEvent-=d;
  }
  因为OnEvent是private的,所以在类外部不能OnEvent(1)触发事件,但是在类内部可以。
  public的方法只有Add和Remove,所以只能+=、-=,其他的操作都是不可以的。
  委托和事件没有可比性,因为委托是类型,事件是对象,下面说的是委托的对象(用委托方式实现的事件)和(标准的event方式实现)事件的区别。事件的内部是用委托实现的。(举例子:三种实现事件方式的区别)。
  因为对于事件来讲,外部只能“注册自己+=、注销自己-=”,外界不可以注销其他的注册者,外界不可以主动触发事件,因此如果用Delegate就没法进行上面的控制,因此诞生了事件这种语法。add、remove。
  事件是用来阉割委托实例的。事件只能add、remove自己,不能赋值。事件只能+=、-=,不能=、不能外部触发事件。 

  使用Delegate的时候很多时候没必要使用一个普通的方法,因为这个方法只有这个Delegate会用,并且只用一次,这时候使用匿名方法最合适。匿名方法就是没有名字的方法。
  ProcessWordDelegate p = delegate(string s)
  {
  Console.WriteLine(s);
  };
  ProcessStringDelegate p = (s) => { Console.WriteLine(s); };
  lambda语法详解:s为参数列表,不需要标注类型,因为变量声明中类型已经说明了。=>后的大括号是方法体。
  如果方法有返回值,并且代码只有一行可以简写i=>i>0,等价于i=>{return i>0;}。

.net技术深入