首页 > 其他 > 详细

程序集

时间:2014-07-07 23:26:23      阅读:344      评论:0      收藏:0      [点我收藏+]

什么是程序集?

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

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

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

使用程序集的好处?

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

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

如何添加程序集的引用?

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

---不能循环添加引用

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

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

访问修饰符

private、protected、public

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

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

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

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

bubuko.com,布布扣
//第一种情况,子类的可访问级别比父类的高
    //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>泛型版本(学了怎么写泛型类就好理解了)

bubuko.com,布布扣
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动态指定。 参考代码:

bubuko.com,布布扣
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代码:

bubuko.com,布布扣

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

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

_methodPtr、_target来自Delegate类。

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

 bubuko.com,布布扣

事件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中,可以通过创建类库的方式创建动态链接库。

 

 

 

 

 

 

程序集,布布扣,bubuko.com

程序集

原文:http://www.cnblogs.com/fanhongshuo/p/3811779.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!