zoukankan      html  css  js  c++  java
  • 程序集

    什么是程序集?

    ---程序集是.net中的概念。

    ---.net中的dll与exe文件都是程序集。(exe与dll的区别?)

    ---程序集(Assembly)。可以看做是一堆相关类打一个包,相当于Java中的jar包(*)。

    使用程序集的好处?

    --程序中只引用必须的程序集,减少程序的尺寸。

    ---程序集可以疯转一些代码,只提供必要的访问接口。

    如何添加程序集的引用?

    ---添加路径、项目引用、GAC(全局程序集缓存)

    ---不能循环添加引用

    (我们调用的类都是位于各个程序集中,如果调用的类没在引用的程序集中,则需要添加对那个程序集的引用。比如ConfigurationManager。)

    访问修饰符、访问级别约束

    访问修饰符

    private、protected、public

    internal(当前程序集)类如果不标注访问级别则是internal级别,也就是只能在程序集内部访问 访问级别约束

    子类的访问级别不能比父类的高。(会暴露父类的成员)

    类中属性或字段的访问级别不能比所对应的类型访问级别高。

    方法的访问级别不能比方法的参数和返回值的访问级别高。

    //第一种情况,子类的可访问级别比父类的高
        //class Person
        //{
    
        //}
    
        //public class Student : Person
        //{
    
        //}
    
        ////第二种情况,类的访问修饰符和类方法的访问修饰符都高于【参数】的访问修饰符
        //class Person
        //{
    
        //}
    
        //public class Test
        //{
        //    public void Show(Person p)
        //    {
        //        Console.WriteLine(p.ToString());
        //    }
        //}
    
        ////第三种情况,类的访问修饰符和类属性或字段的访问修饰符都高于【参数】的访问修饰符
        //class Person
        //{
    
        //}
    
        //public class Test
        //{
    
        //    public Person p;
        //    public void Show()
        //    {
        //        Console.WriteLine(p.ToString());
        //    }
        //}
    
    
        ////第四种情况,类的访问修饰符和类方法的访问修饰符都高于【参数】的访问修饰符
        //class Person
        //{
    
        //}
    
        //public class Test
        //{
        //    public Person Show()
        //    {
        //        return null;
        //    }
        //}
    View Code

    IEnumerable接口

    1.通过反编译查看Array、List<T>、ArrayList、Hashtable、Dictionary<K,V>、Queue、Queue<T>、Stack、Stack<T>、c等集合都实现了该接口。

    2.IEnumerable接口是干什么的?为什么众多的集合都实现了该接口?

        实现这个接口的类型都可以遍历。(数组、集合等都实现了该接口)

         实现了该接口的对象都可以放在foreach中循环遍历。

    3.IEnumerable<T>泛型版本(学了怎么写泛型类就好理解了)

    int[] n = new int[3] { 1, 2, 3 };
    
                IEnumerator ie = n.GetEnumerator();
                while (ie.MoveNext())
                {
                    Console.WriteLine(ie.Current);
                }
    
                Console.ReadKey();
    View Code

    委托1-什么是委托?

    委托是一种数据类型(引用类型),像我们见过的“类”类型一样,只不过“类”类型的变量指向的是一个“对象”,而“委托”类型的变量指向的是一个具体的“方法”。(对方法的包装)

     类的使用

    1.定义类:class Person{public int Age=10;}

    2.实例化类对象: Person p=new Person();

    3.使用类对象:p.Age;

    委托的使用:

    1.委托定义:delegate void SayHiDelegate(string s);

    2.实例化委托变量:SayHiDelegate Say=Hello;

    3.SayHiDelegate Say=new SayHiDelegate(Hello);

    4.Say("大家好”);

    public void Hello(string msg)//Hello方法代码

    {

    Console.WriteLine(msg);

    }

    问题:这不是和直接调用方法一样吗?还要委托干嘛?

    为什么要用委托?

    案例1:【演示案例3,把委托作为字段】//自己编写一个项目生成dll文件,然后别人引用你的项目,调用其中Add()、Times()方法,在Add()、Times()方法中都调用了Method()方法。//问题,如何不修改你的项目,并且别人调用ADd与Time时,Method()方法的执行内容不一样。

    案例2:有一个方法ChangeString(string[] strArr);传入一个字符串数组,在每个元素两边加一个'='.//当我想让元素全部大写,怎么办?(也可以把委托作为‘参数’)。//将用户的代码“注入”到了你的程序中。

    总结:

    1.委托像"占位符"一样,预留了一个”空间“,将来调用者决定”到底这里应该执行什么!“,避免了修改已写好的程序。

    2.程序需要扩展,但写好的代码不需要修改。避免了类之间的紧耦合。”委托“也是为了让我们的程序”更强大“、”更灵活“,有更好的扩展性。

    参考资料《C#图解教程》第15章。

    6*2->i*2,i就是在扣窟窿

    有一些对字符串数组进行逐个处理的函数,转换为大写、

    小写、加引号,如果可以写逐个处理这个数组的多个函数;可以写很多个大写、小写、加引号的小函数,组合出一些函数出来,但是这样的函数仍然是约定死了要调用那些函数的,我想把要调用的函数定义为一个变化的参数,把要它逐个处理的函数定义为一个参数,我传递哪个参数,它就调用哪个参数该多好呀!所以就有了委托。 期望/myfor(e=e.ToUpper()) //期望myfor设定了一个窟窿,开发人员只要填窟窿就可以了!

     委托的使用

    定义委托类型:delegate 返回值类型 委托名类型名(参数列表)

    示例:delegate void SayHelloDelegate(string s);

    声明委托类型变量:

    SayHelloDelegate say=new SayHelloDelegate(SayHello);//注意:这里只能写方法名,不能加().

    --或者SayHelloDelegate say=SayHello;//注意:这里只能写方法名。(这里编译器帮我们new,'委托推断')

    SayHello是一个具体的方法,如下:

    public void SayHello(string msg){Console.WriteLine(msg);}

    注意:这里的say委托可以向普通函数一样调用say("hello").和直接调函数的区别:委托可以理解为”函数指针“,但是它不同于c语言中的”函数指针“,”委托“是类型安全的,它代表了某种类型的方法。

    (类型安全:在编译时,已经确定了数据的类型。保证了执行不会出问题)。

    小写、加引号,如果可以写逐个处理这个数组的多个函数;可以写很多个大写、小写、加引号的小函数,组合出一些函数出来,但是这样的函数仍然是约定死了要调用那些函数的,我想把要调用的函数定义为一个变化的参数,把要它逐个处理的函数定义为一个参数,我传递哪个参数,它就调用哪个参数该多好呀!所以就有了委托。 期望/myfor(e=e.ToUpper()) //期望myfor设定了一个窟窿,开发人员只要填窟窿就可以了!

    小写、加引号,如果可以写逐个处理这个数组的多个函数;可以写很多个大写、小写、加引号的小函数,组合出一些函数出来,但是这样的函数仍然是约定死了要调用那些函数的,我想把要调用的函数定义为一个变化的参数,把要它逐个处理的函数定义为一个参数,我传递哪个参数,它就调用哪个参数该多好呀!所以就有了委托。 期望/myfor(e=e.ToUpper()) //期望myfor设定了一个窟窿,开发人员只要填窟窿就可以了!

    委托使用案例1:数据验证控件

    编写UserControl。UserControl内有一个textbox,需要对textbox中的值进行验证。将验证时机、验证报错等写在UserControl中,把数据的不同的校验逻辑通过delegate动态指定。 参考代码:

    public Validate Validator;
    private void textBox1_Validating(object sender, CancelEventArgs e)
            {
                if (Validator(textBox1.Text) == false)
                {
                    MessageBox.Show("数据非法");
                }
            }
    public delegate bool Validate(string txt);   //用户只需设置不同的Validator即可。
    View Code

    修改校验的报错方式。userControl是别人写的控件,使用者不用关心什么时候校验,校验出错的时候怎么报错,只要关心对数据进行校验就可以了,使用控件的人不用懂WinForm控件的开发。 控件使用者:不用关心控件在什么时候进行数据校验、校验出错怎么报错,只要指定校验算法就可以。控件开发者:不用把校验算法写死在控件里。

     委托使用案例2

    案例3:(建两个项目来演示)也可把委托作为参数。

    案例4:MySort.DoSort(),实现对int,string,Person类型的排序。提示:string按字符串长度排序,Person按Age排序。

    练习1:实现案例5的Person按Age排序。

    面向对象编程,遵循“低耦合、高内聚”的编程原则。

    “低耦合”:降低不同模块之间的的关联程度,避免修改一个模块影响其他。

    “高内聚”:加强同一个模块之间的内容聚合度,同一个模块中的代码相关性很强,“单一职责原则”。

    关于案例6,:可以采用冒泡排序法。尽量掌握,面试的时候如果考到排序,如果连最简单的冒泡排序都写不出来就不太好。在.net framework类库中,List<T>的sort()方法也是可以接受一个比较器的。如果每次都重新编写一种排序方法的话,虽然不难,也能实现但是违反了DRY(Don’t Repeat Yourself)原则(不要写重复代码)。

     委托使用案例3(作业)

    练习4:求给定数组中的最大值

    int[] values = { 30,90,7,88,3};
    int max = values[0];
    foreach (int i in values)
    {
        if (i > max)
          {
             max = i;
          }
    }
    Console.WriteLine(max);
    “aa”,”aaaa”,”aaaaaaa”
    “aaaaaaa”
    Object[]
    Object[] n={1,2,4};
    Object[] str={“a”,”aa”,”aaa”};

    //以上代码是选出最大整数的代码。这段代码只能对int数组取最大整数,如果要实现”字符串数组最长的字符串“、”Person数组取最大的年龄”则每次都要重复写代码。

    委托的组合(多播委托、委托连)

    delegate void SayHelloDelegate(string s);

    多播委托绑定方法的几种方式:

    --SayHelloDelegate say=new SayHelloDelegate(SayHello)+new SayHelloDelegate(SayHi);//使用+把两个委托相加时,只能是"委托“相加,不能直接把”方法名“相加。

    ---快捷方式(增加方法)

    -say=SayHello;

    say+=SayHI;//不能say=say+SayHi;(两个方法名无法相加)

    --快捷方式(取消方法,将此方法从委托中移除)

    say-=SayHi;

    say-=SayHello;//减的时候注意:加的哪个对象,减的哪个对象,否则”减“不掉。

    多播委托中的一些问题

    返回值不为void时,如何处理返回值?

    委托绑定多个方法后,其中一个方法执行发生异常后面的方法还会继续执行吗?不会!

    一个重要的方法GetInvocationList();//返回一个Delegate[]类型。Delegate类是一个抽象类,是所有委托的父类。

    委托的本质1(*)

    其实就是一个类把方法包装了一下,委托都继承自System.MulticastDelegate,而System.MulticastDelegate又继承自System.Delegate

    多播委托就是有一个委托数组,依次调用。

    查看自己写的委托的IL代码:

    委托的本质2(*帮助理解多播委托)

    委托类( System.MulticastDelegate )的3个重要成员

    _methodPtr、_target来自Delegate类。

    _invocationList来自MulticastDelegate类。//实际上是一个Delegate[]类型

     

    事件1

       “事件”的本质其实就是一个对象(一个委托类型的变量),委托是一种类型。 “事件”只是对“委托变量”的包装,其本质依然是委托。

        实现事件的基础是“委托”,没有“委托”就没有“事件”。

       案例:用委托实现一个“三连击按钮”。//注意在调用委托前,判断委托对象是否为null。(为什么要判断为null?)

    直接用委托会有一些问题:

    用户可以把之前注册的方法全部覆盖掉

    用户可以随意的调用委托 有些时候不想让用户随意覆盖之前注册的方法,不想让用户随意调用委托。怎么办?

    事件: 使用event关键字,简化了使用委托时的语法而已。最终编译器生成的代码其实就是委托。

    声明事件:event 委托名 事件名

    示例:event SayHelloDelegate say;

    事件语法:event ProcessWordDelegate{add{...},remove{...}}

    add、remove和属性、索引一样最终都编译成两个方法。

    如果是简单的增加委托,没有特殊的判断逻辑可以简写,一般情况下都是简写。

    加了event关键字实现事件机制的好处:用了event事件,不可以修改事件已经注册的值;不可以冒充进行事件通知了。在IntUC类外部就不能通过OnInt(3)的方式调用注册的委托了。只能+=、-=!

    课上练习:实现连续点击三次触发TriClick事件的按钮(用UserControl),用EventHandler这个委托就行。注意不要把判断次数的代码写到用控件的窗口上,否则就违反了封装的原则。 动态设置控件事件

    exe与dll的区别?

     EXE是可以单独运行的程序。

    DLL是不能单独运行,一般是由EXE程序来调用DLL的函数。

    DLL一般是封装了一些共享的例程和资源,它通常是一个可以被其它应用程序调用的程序模块。一般扩展名为dll。

     它与EXE有些类似,但动态链接库不能被直接执行,只能被其它EXE或者动态链接库调用。

     在.NET中,可以通过创建类库的方式创建动态链接库。

  • 相关阅读:
    关于博客
    latex句首缩进空格
    javable 之Iterable
    javable之Comparable
    常量池与Integer和String的“==”
    静态多态与动态多态
    String和StringBuilder效率不同的原理
    equals和hashcode
    Eclipse里面使用checkstyle(Google style)
    矩阵链乘问题
  • 原文地址:https://www.cnblogs.com/fanhongshuo/p/3811779.html
Copyright © 2011-2022 走看看