程序集

什么是程序集?

---程序集是.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;
    //    }
    //}

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();

委托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即可。

修改校验的报错方式。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中,可以通过创建类库的方式创建动态链接库。

程序集,布布扣,bubuko.com

时间: 2024-12-06 03:59:08

程序集的相关文章

SQL Server通过外部程序集注册正则表达式函数(CLR函数)

1.下载dll程序集(通过C#编写的支持正则的方法),百度网盘下载: 1.1如果只想用,可以直接下载MSSQLRegexExtend.dll https://pan.baidu.com/s/1qX8eHa8 1.2正则程序集对应的解决方案MSSQLRegexExtend.sln,已打包 https://pan.baidu.com/s/1qXZja9m 2.SQL Server数据库注册程序集 CREATE ASSEMBLY AssemblyRegex from 'D:\MSSQLRegexExt

《Inside C#》笔记(完) 程序集

程序集内部包含了各种相关的模块.资源文件.配置文件等,将这些在功能上相关的文件整合到单个文件中,以便于部署和维护.使用C#编译器编译程序时,生成的便是程序集. 一.清单数据 a)如果编译的是独立应用程序或是dll,清单数据会被保存在生成的PE文件中,这被称为单文件程序集:但如果是多文件程序集,清单数据会单独保存. b)清单数据包含的内容有:程序集的名称:版本信息:签名:文件:引用的程序集:类型:自定义Attribute:产品信息. 二.程序集的作用 a)将多个模块打包成程序集可以带来性能的提升,

为什么.Net平台不支持程序集卸载(Assembly.Unload)?

我们知道在.net平台中反射提供了在运行时动态的获得程序或程序集中每一个类型(包括类.结构.委托.接口和枚举等)的成员和成员的信息,从而使得我们开发人员在运行时能够利用这些信息构造和使用对象.我们知道反射中可以通过System.Reflection.Assembly命名空间下的 Assembly.Load 动态的加载程序集信息,获取我们想要的一切信息.那么当我们动态加载完程序集并对其使用完之后,我们想卸载掉它,不想在内存中留下垃圾信息,这时我们发现Assembly并没有提供Assembly.Un

.NET 程序集Assembly使用

概述 一直以来,我们都在用C#编写程序,编写程序的时候,我们用到继承.多态.接口以及泛型,我们也都明白子类可以继承抽象类,并能够重写父类的抽象方法,可是大家是否想过,如下几个问题: 1.凡树必有根和叶,类的继承也如此,如何通过程序集查找所有继承父类的之类的程序集名称? 2.如果程序B被其他程序调用,如何通过程序集查询调用B的所有程序? 3.如何查询当前项目通过添加引用了哪些程序集? 带上上面的三个问题,我们来学习下.NET 程序集 Assembly. 查询继承父类的程序集合BaseType .N

未能加载文件或程序集“”或它的某一个依赖项。系统找不到指定的文件

连续两天都为这个运行时错误“类型初始值设定项引发异常”而烦恼,调试也不知道哪里出了问题.上网Google一下,一大堆相同的问题,可是按照那些方法折腾来折腾去,问题还是一样.最后在CSDN上发帖子问了,果然“重赏之下必有勇夫”,很快就有高手回复了,问题也随着解决了.哈哈.在此写个随笔,以后如果大家遇到类似问题,也可参考一下,自己也做个备忘,不然放在电脑上,又找不到,我的电脑文件到处乱放,有时连我自己都找不到^_^. 问题是这样嘀: 项目采用了三层架构和工厂模式,并借鉴了PetShop的架构,因为这

未能加载文件或程序集“DotNetOpenAuth.Core, Ve

“/”应用程序中的服务器错误. 未能加载文件或程序集“DotNetOpenAuth.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=2780ccd10d57b246”或它的某一个依赖项.系统找不到指定的文件. 说明: 执行当前 Web 请求期间,出现未经处理的异常.请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息. 异常详细信息: System.IO.FileNotFoundException: 未能加载文件或程

程序集=命名空间

命名空间是用来组织和重用代码的编译单元.如同名字一样的意思,NameSpace(名字空间),之所以出来这样一个东西,是因为人类可用的单词数太少,并且不同的人写的程序不可能所有的变量都没有重名现象,对于库来说,这个问题尤其严重,如果两个人写的库文件中出现同名的变量或函数(不可避免),使用起来就有问题了,为了解决这个问题,引入了名字空间这个概念,通过使用 namespace xxx;你所使用的库函数或变量就是在该名字空间中定义的,这样一来就不会引起不必要的冲突了. 所谓namespace,是指标识符

.net 程序集的加载与反射

一. 程序集的加载: 在CLR内部使用System.Reflection.Assembly类的静态Load方法尝试加载程序集. //LoadFrom 根据已知的程序集路径加载程序集 Assembly a = Assembly.LoadFrom("@c://query.dll");

C# 动态加载程序集dll (实现接口)

一.程序集(接口程序集):LyhInterface.Dll namespace LyhInterface{    public interface ILyhInterface    {        void Run();    }} 二.程序集(实现接口的程序集):LyhClassLibrary1.dll, LyhClassLibrary2.dll,LyhClassLibrary3.dll,所有程序集引用:LyhInterface.dll namespace LyhClassLibrary1{

C#-VS程序集

程序集即代码组,可以是单个文件或多个文件,按一个整体部署,但可指定自身调用其他程序集的版本. 推出原因 为解决dll地狱而推出,也可解决其他问题.dll地狱,a应用使用dll版本1,b应用使用dll版本2,传统的com(一般用dll执行)模式,会自动调用最新版本的dll,如果这个dll不向后兼容(大多dll都不向后兼容),导致装了b应用后,a应用不能使用. .net模式,在程序集中,指定使用哪个版本,在调用时,默认使用指定的版本,解决了dll地狱问题. 程序集信息 主版本,次版本.修订号.内部版