委托、泛型与事件
.net framework相关面试题

1.请简述.NET Framework是什么?
Framework和.NET Core有什么区别?
3.请解释一下什么是装箱和拆箱?
4.什么是垃圾回收?请简述.NET Framework中的垃圾回收机制。
5.请解释一下什么是委托?在.NET Framework中如何使用委托?
6.什么是事件?在.NET Framework中如何使用事件?
7.请简述一下.NET Framework中的异常处理机制。
8.请解释一下什么是泛型?在.NET Framework中如何使用泛型?
9.请解释一下什么是LINQ?在.NET Framework中如何使用LINQ?
10.请解释一下什么是反射?在.NET Framework中如何使用反射?
以上问题只是.NET Framework面试中的一部分,具体的面试题还会根据面试官的要求和应聘的职位有所不同。
委托和事件的区别

委托和事件的区别委托的本质,是⼀个类,⽽事件,是⼀个委托类型的私有变量加上两个公有⽅法(事件的+=和-=),这是本质区别。
打个⽐⽅,string 也是⼀个类,⽽string s = "a",这个s是string类型的⼀个变量(略有不恰当,为了⽅便直观理解)。
public delegate void myDel();相当于你创建了⼀个myDel的类,所以委托可以在任何地⽅创建,类需要实例化,所以委托需要实例化,要myDel m = ……;申明⼀个事件 public event myDel myEvent;事件myEvent是⼀个myDel类型的⼀个变量,因为是变量,所以事件只能在类⾥⾯申明,不需要实例化,有点类似与上⾯的那个m,当然不全是,他还有两e79fa5e98193e4b893e5b19e31333366306531个⽅法(+=,-=),调⽤⼀次+=⽅法,myEvent += MethodA;其实是把MethodA⽅法,封装成⼀个myDel类型的委托对象,然后把这个对象的引⽤赋值给这个myEvent变量。
如果多次调⽤+=,就是多个⽅法封装成了多个myDel委托对象,然后这些委托对象放在⼀个列表⾥⾯,然后myEvent就指向这个列表,触发的时候,就是调⽤这个列表⾥⾯的所有委托的Invoke⽅法。
转delegate是C#中的⼀种类型,它实际上是⼀个能够持有对某个⽅法的引⽤的类。
与其它的类不同,delegate类能够拥有⼀个签名(signature),并且它"只能持有与它的签名相匹配的⽅法的引⽤"。
它所实现的功能与C/C++中的函数指针⼗分相似。
它允许你传递⼀个类A的⽅法m给另⼀个类B的对象,使得类B的对象能够调⽤这个⽅法m。
但与函数指针相⽐,delegate有许多函数委托和事件在 .Net Framework中的应⽤⾮常⼴泛指针不具备的优点。
⾸先,函数指针只能指向静态函数,⽽delegate既可以引⽤静态函数,⼜可以引⽤⾮静态成员函数。
委托应用场景[摘]
![委托应用场景[摘]](https://img.taocdn.com/s3/m/424e79b1f021dd36a32d7375a417866fb84ac028.png)
委托应⽤场景[摘]委托除了实现事件外,还能够实现很多⾮常有⽤的语⾔特性。
1、Lambda 表达式。
Lambda 表达式有两种存在⽅式,⼀是匿名委托,⽽是表达式树。
2、匿名⽅法。
不指定名称的委托成为匿名委托。
有时候⾮常有⽤,如在绑定事件处理程序或者创建线程时。
3、多线程同步以及跨线程操作。
4、泛型委托。
5、基于委托的逆变 (Contravariance) 和协变 (Covariance)。
跨线程访问实例不允许在winform中直接跨线程访问控件例如:public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { Thread thread = new Thread(ThreadFuntion); thread.IsBackground = true; thread.Start(); } private void ThreadFuntion() { while (true) { this.textBox1.Text = DateTime.Now.ToString(); Thread.Sleep(1000); } } }会看到系统抛出⼀个异常:Cross-thread operation not valid:Control 'textBox1' accessed from a thread other than the thread it was created on .这是因为.net 2.0以后加强了安全机制,不允许在winform中直接跨线程访问控件的属性.那么怎么解决这个问题呢, 就是使⽤delegate和invoke来从其他线程中控制控件信息例如:public partial class Form1 : Form { private delegate void FlushClient();//代理 public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { Thread thread = new Thread(CrossThreadFlush); thread.IsBackground = true; thread.Start(); } private void CrossThreadFlush() { while (true) { //将sleep和⽆限循环放在等待异步的外⾯ Thread.Sleep(1000); ThreadFunction(); } } private void ThreadFunction() { if (this.textBox1.InvokeRequired)//等待异步 { FlushClient fc = new FlushClient(ThreadFunction); this.Invoke(fc);//通过代理调⽤刷新⽅法 } else { this.textBox1.Text = DateTime.Now.ToString(); } } }。
C#基础知识学习之?委托(delegate)与事件(event)之间的介绍

C#基础知识学习之✨委托(delegate)与事件(event)之间的介绍委托(delegate) 与事件(event)前言在之前的文章里介绍了C#中的委托(delegate)(Action、Func、Predicate)的基本含义及用法那本篇文章在这里还要介绍一个跟委托有很大关系的小伙伴——C#中的事件(event)事件跟委托是有很大联系的,所以也就导致很容易分不清他们两个,以及什么时候用这两个上面有博客提到委托,想单独了解委托的可以去看一下,本篇文章主要说一下什么是事件以及事件与委托的区别委托和事件的定义委托在这里再说一遍委托跟事件的简单定义(没有搜到特别准确的,都是大概定义,理解万岁)委托:delegate 是一种可用于封装命名或匿名方法的引用类型。
委托类似于 C++ 中的函数指针;但是,委托是类型安全和可靠的。
委托是一种动态调用方法的类型,属于引用型。
委托是对方法的抽象和封装。
委托对象实质上代表了方法的引用(即内存地址)委托允许将方法作为参数进行传递。
委托可用于定义回调方法。
委托可以把多个方法链接在一起。
这样,在事件触发时可同时启动多个事件处理程序。
委托签名不需要与方法精确匹配。
事件事件:事件是特殊类型的多路广播委托,仅可从声明它们的类或结构(发行者类)中调用。
如果其他类或结构订阅了该事件,则当发行者类引发该事件时,会调用其事件处理程序方法。
事件表示C#中已定义的一个对象,即处理通知过程的对象通常,每个事件的发生都会产生发送方和接收方。
在.net框架中,事件是将事件发送者(触发事件的对象)与事件接受者(处理事件的方法)相关联的一种代理类,即事件机制是通过代理类来实现的。
当一个事件被触发时,由该事件的代理来通知(调用)处理该事件的相应方法委托和事件的区别简单说了一下两者的定义,眼神好的小伙伴这时候就会发现,事件的说明里有提到一句话:“事件也可以算一种特殊的委托”,这句话不是特别准确,但是也不妨可以这样理解。
C#委托(delegate)、泛型委托和Lambda表达式

C#委托(delegate)、泛型委托和Lambda表达式⽬录# 什么是委托1、从数据结构来讲,委托是和类⼀样是⼀种⽤户⾃定义类型。
2、委托是⽅法的抽象,它存储的就是⼀系列具有相同参数和返回类型的⽅法的地址。
调⽤委托的时候,委托包含的所有⽅法将被执⾏。
# 委托声明、实例化和调⽤1、声明委托是⼀种特殊的类,因此委托的声明与类的声明⽅法类似,在任何可以声明类的地⽅都可以声明委托。
委托声明⽤delegate关键字,同时委托要指明⽅法参数和返回值,写法与⽅法类似。
综合类的声明和⽅法的声明,委托声明写成如下形式:[访问修饰符] delegate 返回值类型委托名(形参列表);public delegate void MyDel();//定义了⼀个委托MyDel,它可以注册返回void类型且没有参数的函数public delegate void MyDel1(string str);//定义了⼀个委托MyDel1,它可以注册返回void类型且有⼀个string作为参数的函数public delegate int MyDel2(int a,int b);//定义了⼀个委托MyDel2,它可以注册返回int类型且有两个int作为参数的函数2、委托的实例化与普通类的使⽤⽅法相同,声明了委托之后,我们必须给委托传递⼀个具体的⽅法,才能在运⾏时调⽤委托实例。
委托实例包含了被传递给它的⽅法的信息,在运⾏时,调⽤委托实例就相当于执⾏它当中的⽅法。
委托实例化格式如下:委托类名委托实例名 = new 委托类名(Target) ;其中,委托实例名是⾃定义的名称,Target是要传⼊的⽅法的名称。
注意,Target是⽅法的引⽤,不能带()。
带()的话是该⽅法的调⽤。
区分引⽤和调⽤。
委托的实例化还有⼀种简单的⽅法:委托类名委托实例名 = Target;在需要委托实例的地⽅直接传⼊Target引⽤即可,C#编译器会⾃动根据委托类型进⾏验证,这称为“委托推断”。
委托和事件的关系

委托和事件的关系1.委托的定义: delegate 是⼀种可⽤于封装命名或匿名⽅法的引⽤类型。
委托类似于 C++ 中的函数指针;但是,委托是类型安全和可靠的(MSDN的定义)。
委托是引⽤类型。
委托还有⼀些泛型委托: Action<T>只能委托⽆返回值的⽅法,⽽且可以传⼊的参数个数在0-16之间。
Predicate<T>委托返回bool值的的⽅法,只能输⼊⼀个参数类型。
public class People{public event Predicate<int> Compare;public void Start(){if (pare(1))Console.WriteLine("开始");elseConsole.WriteLine("等待");}}//调⽤People p = new People();pare += (int preValue) => { if (preValue == 1)return true; else return false; };p.Start(); Func<TResult>绑定⼀个参数(范围0-16)但却返回 TResult 参数指定的类型值的⽅法 例如:Func<T,TResult> Func<T,T,TResult> Func<T,T,...,TResult>例如:2.事件的定义: 事件是⼀种特殊的委托,是委托的⼀种特殊应⽤。
委托是事件的基础,通过将委托与命名⽅法或者匿名⽅法关联,可以实例化委托,然后委托实例化相应的事件。
事件的使⽤⽅式:事件能通过+=和-=两个⽅式注册或者注销对其处理的⽅法,使⽤+=与-=操作符的时候,系统会⾃动调⽤对应的add_XXX、remove_XXX 进⾏处理。
事件处理⽅法的绑定:在绑定事件处理⽅法的时候,事件出现在+=、-= 操作符的左边,对应的委托对象出现在+=、-= 操作符的右边。
csharp练习题

C练习题一、基础语法1. 声明一个整型变量并赋值为10。
2. 声明一个浮点型变量并赋值为3.14。
3. 声明一个字符串变量并赋值为"Hello, World!"。
4. 声明一个布尔变量并赋值为true。
5. 创建一个名为`MyClass`的类,并在其中声明一个名为`myField`的私有整型字段。
6. 在`MyClass`类中添加一个构造函数,接受一个整型参数并赋值给`myField`字段。
7. 在`MyClass`类中添加一个名为`PrintField`的方法,打印出`myField`字段的值。
二、控制结构8. 编写一个程序,使用`if`语句判断一个整数变量是否大于0。
9. 编写一个程序,使用`switch`语句根据整数变量的值输出对应的星期名称。
10. 编写一个程序,使用`for`循环打印1到10的数字。
11. 编写一个程序,使用`foreach`循环遍历一个整数数组并打印每个元素。
12. 编写一个程序,使用`while`循环计算1到10的阶乘。
三、函数和方法13. 编写一个名为`Add`的方法,接受两个整数参数并返回它们的和。
14. 编写一个名为`Multiply`的方法,接受两个整数参数并返回它们的乘积。
15. 编写一个名为`PrintNumbers`的方法,接受一个整数参数,打印从1到该参数的所有数字。
16. 编写一个名为`ReverseString`的方法,接受一个字符串参数并返回其反转后的字符串。
17. 编写一个名为`FindMax`的方法,接受一个整数数组参数并返回数组中的最大值。
四、面向对象18. 创建一个名为`Person`的类,包含姓名和年龄两个属性。
19. 在`Person`类中添加一个构造函数,接受姓名和年龄作为参数。
20. 在`Person`类中添加一个名为`PrintInfo`的方法,打印出该人的姓名和年龄。
21. 创建一个`Student`类,继承自`Person`类,并添加一个名为`Grade`的属性。
c#委托、泛型委托和匿名方法

c#委托、泛型委托和匿名⽅法题外话:别指望看第⼀遍书就能记住和掌握什么——请看第⼆遍、第三遍。
本⼈⼥猿⼀枚,2年⼯作经验,喜欢钻研,喜欢创新,闲暇之余喜欢写写博客,深知⾃⾝能⼒薄弱,如表达错误、不当之处请园友们多多指出,互相交流。
最近在学习lambda表达式,lambda表达式与匿名⽅法有着密切联系,⽽匿名⽅法⼜离不开委托,索性我就围绕委托、泛型、匿名⽅法做个总结,以加深我的理解,总结的内容很基础,希望各位⼤神看后勿喷。
⾸先,引⽤MSDN上的原话解释这⼏个名词:委托:是⼀种引⽤⽅法的类型。
⼀旦为委托分配了⽅法,委托将与该⽅法具有完全相同的⾏为。
泛型:泛型是 2.0 版 C# 语⾔和公共语⾔运⾏库 (CLR) 中的⼀个新功能,使⽤泛型类型可以最⼤限度地重⽤代码、保护类型的安全以及提⾼性能。
匿名⽅法:在 2.0 之前的 C# 版本中,声明的唯⼀⽅法是使⽤。
C# 2.0 引⼊了匿名⽅法。
要将代码块传递为委托参数,创建匿名⽅法则是唯⼀的⽅法。
如果使⽤匿名⽅法,则不必创建单独的⽅法,因此减少了实例化委托所需的编码系统开销。
MSDN解释的挺透彻的了,我就不多嘴了,下⾯看看具体的实例。
委托有了委托,我们就可以把⽅法当成参数来传递,⽤委托对象调⽤它所指向的⽅法,委托与c++中的指针很相似,但是委托是类型安全的。
⾸先先看⼀个例⼦:⼩张委托⼩明去打热⽔://定义⼀个委托public delegate void GetHotWaterEventHandler();static void Main(string[] args){//声明⼀个委托对象,并绑定⼀个⽅法GetHotWaterEventHandler Getwater = new GetHotWaterEventHandler(MyHotWater);Getwater();//使⽤委托调⽤⽅法Console.ReadKey();}//⼩明打热⽔⽅法private static void MyHotWater(){Console.WriteLine("Oh,NO!命苦的我⼜要去打热⽔了!");}上⾯就是⼀个简单的委托,该委托没有返回值,没有传⼊参数,实际使⽤时,委托的返回值和形参要与绑定的⽅法相同,否则会报错。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
匿名方法作为函数参数
invokeDelegate( delegate(int i int j) i,int { returni +j; return i + j; },100,200);
Func<>范型委托所能接收的函数都有返回值, Func<>范型委托所能接收的函数都有返回值 那么,有没有接收返回void的函数的系统托
publicdelegatevoidAction(); bli d l t id A ti () publicdelegatevoidAction<T>(Tobj); publicdelegatevoidAction<T1,T2>(T1arg1,T2arg2) publicdelegatevoidAction<T1,T2,T3>(T1arg1,T2arg2,T3arg3) publicdelegatevoidAction<T1,T2,T3,T4>(T1arg1,T2arg2,T3arg3,T4arg4)
所有这些看上去复杂的声明,其实是很简单的: 所有 看 去复杂的声明 其实是很简单的 最后一个参数是委托所接收函数的返回值,前 面的参数(如果有的话)就是委托所接收函数 数 委 接收 数 的形参。
Func<>应用实例
Func<int,int,long>add=delegate(int a,int b) { returna*b; }; Console.WriteLine(add(5,10));
C#编译器对委托的处理方法
publicdelegateint MathOptDelegate(int value1,int value2);
上述委托将被编译器转换为:
publicclassMathOptDelegate :System.MulticastDelegate { publicMathOptDelegate(Objecttarget,Int32methodPtr); p publicvoidvirtualInvoke(Int32value1,Int32value2); ( , ); publicvirtualIAsyncResult BeginInvoke( , , y , j j ); Int32value1,Int32value2,AsyncCallbackcallback,Objectobject); publicvirtualvoidEndInvoke(IAsyncResult result); }
上述定义的委托,接收拥有一个到四个参 数,返回值类型为 数,返回值类型为void的函数。 的函数
Action<>实例
privatestaticvoidShowMessage(stringinfo) i t t ti id Sh M (ti i f ) { Console.WriteLine(info); ( ) } staticvoidMain(string[]args) { Action<string>act=ShowMessage; act("Hello"); ( ); }
委托的组合与分解
事实上,一个委托变量可以“引用”多个 函数,请看Demo( UseDelegate)。 g 引用多个函数的委托变量称为“多路委 托 托”。
多路委托变量 函数 函数 函数
委托调用链
7
从前面介绍的例子来看,使用委托 有以下几个步骤:
定义委托类型 定义 个或多个符合委托类型的函数 定义一个或多个符合委托类型的函数 定义委托类型的变量 将第2步定义的函数引用“挂接”到第3步 定义的变量,以形成 个 函数调用链 定义的变量,以形成一个“函数调用链”。 5. 通过委托变量“间接”调用函数调用链 1. 2. 2 3. 4.
匿名方法小结
在 在.NET2.0时代,匿名方法主要是作为简化 时代 匿名方法主要是作为简化 代码的手段而引入到C#2.0语法特性中的。 然而,也许设计者事先也并没有预想到, 这一原先仅出现在特定编程语言中的特性, 这 原先仅出现在特定编程语言中的特性 却成为了.NET3.5中的重要技术——LINQ的 基础之一。 基础之
2.3.2用于对象操作的委托
对象比较
publicdelegateintComparison<T>(Tx,Ty) 返回值 小于 0 0 大于0 说明 x<y y x=y x>y
使用Comparison<T>委托
Comparison<T>委托引用的函数可用于比较 委托引用的 数 用 比较 两个对象的大小。 示例:UseComparisonDelegate 使用一个对象比较器来确定两个对象“谁 使用 个对象比较器来确定两个对象“谁 大谁小”。List<T>对象使用此对象比较器进 行排序。
自定义事件的步骤(2)
定义 个事件委托 定义一个事件委托
publicdelegatevoidMyClickEventDelegate( Objectsender, MyClickEventArgs e );
2.2泛型委托
技术背景
泛型技术在 泛型技术在.NET2.0时代被加入到C#语言特 时代被加 到 言特 性中,因此,从.NET2.0开始,委托也开始 支持泛型,这就是“泛型委托”。
泛型委托示例
Demo:UseGenericDelegate 示例分析: 泛型委托的使用与普通委托类似,不同之 处在于使用泛型委托时需要指定类型参数。 处在于使用泛型委托时需要指定类型参数
系统预定义委托
.NET基类库中的预定义委托 NET基类库中的预定义委托
为了方便软件 程师 为了方便软件工程师,.NET基类库中针对在 基类库中针对在 实际开发中最常用的情形提供了几个预定 义好的委托,这些委托可以直接使用,无 需从头定义自己的委托类型。 预定义委托在.NET基类库中用得很广,需要 予以关注。 予以关注
Predicate<T>委托示例
Demo:UsePredicateDelegate 特点: 判断条件一般是“外在的”,而非由数据 自身指定的(比如要查找数组中最大的记 录)就不适合采用此委托
4使用委托定义事件
EventHandler委托
许多事件(比如事件的Click)的响应函数都拥有一 许多事件(比如事件的Click)的响应函数都拥有 致的格式,.NET提供了一个EventHandler委托用于 引用事件响应函数。
匿名方法其实是将方法定义与委托变量赋值两个步骤合在 一起。 起
探索匿名方法
使用 使用Reflectoor或者ilDasm查看C#编译器处 或者 查看 编译 处 理UseAnonymousMethod示例程序: y
委托类型可作为函数形参
一个接收委托类型变量作为参数的函数: 个接收委托类型变量作为参数的 数
委托 委托(Delegate):是.NETFramework对C# 是 对 和等编程语言特性的一个重要扩充。 委托是.NET中的一些重要技术,比如事件、 异步调用和多线程开发的技术基础。 异步调用和多线程开发的技术基础 委托在.NET开发中应用极广,每一名.NET软 件工程师都必须了解委托。
深入了解事件的技术内容
在 S 中可以查到 C 在MSDN中可以查到,Control.Click事件的定义如下: l Cli k事件的定义如下
p publiceventEventHandler Click; ; 由此可知,Click事件实际上就是一个EventHandler委托 类型的一个变量罢了! 类型的 个变量罢了! 还记得委托变量可以引用一个由多个函数首尾相接而成的 “函数调用链”吗? 利用这个特点,我们可以让Click事件发生时,连续调用多 个事件响应函数。 个事件响应函数 Demo:UseEventHandler2
引例:FirstDelegateExample
引例分析 引例分析: 1. 委托可以看成是 个函数的 容器 ,将 1 委托可以看成是一个函数的“容器”,将 某一具体的函数“装入”后,就可以把它 当成函数一样使用。 当成函数一样使用 2. 一个委托类型的变量,可以引用任何一个 满足其要求的函数。 从这点意义上看,委 托类似于C语言中的 函数指针 。 托类似于C语言中的“函数指针”。
2.3.1通用委托
Func<>委托
pub c de ega e esu u c publicdelegateTResult Func<TResult>(); esu (); publicdelegateTResult Func<T,TResult>(Targ) publicdelegateTResult Func<T1,T2,TResult>(T1arg1,T2arg2) publicdelegateTResultFunc<T1,T2,T3,TResult>( public delegate TResult Func<T1 T2 T3 TResult>( T1arg1,T2arg2,T3arg3) publicdelegateTResultFunc<T1,T2,T3,T4,TResult>( T1arg1,T2arg2,T3arg3,T4arg4) T1 arg1 T2 arg2 T3 arg3 T4 arg4)
查找对象
publicdelegatebool P di t T (T bj) bli d l t b l Predicate<T>(Tobj);
Predicate<T>委托接收一个函数引用,在函 Predicate<T>委托接收 个函数引用,在函 数内部书写代码表明此对象应满足的条件, 满足返回true。