C# 第四章 高级语言的特性

4.1 委托(delegate)

大致上—函数指针

委托是对函数原型的包装

委托的声明

public delegate double MyDelegate( doublex)

委托的实例化

MyDelegated d2 =new MyDelegate(obj.myMethod);

委托的调用

委托变量名(参数列表)

d2(8.9)

 

函数积分的运算

using System;

 

delegate double Fun(double x );

 

 

 

public class DelegateIntegral

{

public static voidMain()

{

Fun fun = newFun(Math.Sin);

double d = Integral(fun, 0, Math.PI/2, 1e-4 );

Console.WriteLine( d );

 

Fun fun2 = new Fun(Linear );

double d2 = Integral(fun2, 0, 2, 1e-3 );

Console.WriteLine( d2 );

 

Rnd rnd = new Rnd();

double d3 = Integral(new Fun(rnd.Num), 0, 1, 0.01 );

Console.WriteLine( d3 );

}

 

static double Linear(double a )

{

return a*2+1;

}

 

class Rnd

{

Random r = new Random();

public double Num(double x )

{

return r.NextDouble();

}

}

 

static doubleIntegral(Fun f, double a, double b, double eps)// 积分计算

{

int n,k;

doublefa,fb,h,t1,p,s,x,t=0;

 

fa=f(a);

fb=f(b);

 

// 迭代初值

n=1;

h=b-a;

t1=h*(fa+fb)/2.0;

p=double.MaxValue;

 

// 迭代计算

while (p>=eps)

{

s=0.0;

for (k=0;k<=n-1;k++)

{

x=a+(k+0.5)*h;

s=s+f(x);

}

 

t=(t1+h*s)/2.0;

p=Math.Abs(t1-t);

t1=t;

n=n+n;

h=h/2.0;

}

return t;

}

 

}

 

 

委托的合并

多播MultiCastDelegate

一个委托实例中可以“包含”多个函数

调用委托,就是调用其中多个函数

多个函数间的先后顺序是没有意义的

返回值也就没有太多意义

 

运算符+-  +=  -=

动态地增减其中的函数

提高了程序的灵活性

 

委托的转换

按声明的名称判断

以下两个不能互相转换或加减

delegate void D(int a)

delegate void B (int a)

 

委托的相等

按内容(即其中“包含的函数”)来判断

有点点像两个字符串的“相等”与否的判断

 

委托相当于函数指针

但它类型更安全,是引用类型

且功能更强大,有多播功能

 

编程实例:函数的绘图txt  委托的多播.txt

 

 

4.2事件

事件----回调函数

用户界面中的事件

按钮点击事件

基本的写法

 

事件的声明

public event 委托名 事件名;

事件的注册与移除

事件名+=或-=

在事件所在类的外面只能用以上两个运算符

事件的发生(激发)

事件名(参数列表)

相当于回调所注册的函数

 

网络爬虫

EventWhenDownload.cs

 

定义及使用事件的6步曲

公用的:

声明事件参数类:class xxxEventArgs{}

声明委托:delegate void xxxEventHandler(obj ,args)

在一个类中:

定义时间:public event 类型名称

发生事件:事件名(参数)

在别的类中:

定义一个方法:void方法名(obj,args)

注册时间:  xxx.时间+= new 委托(方法名)

 

事件与委托的关系

事件一定有相关的委托类型

与委托实例一样,事件也“包含”多个函数

事件的运算受更多限制(在类外只能用+=或-=)

事件比委托实例更复杂:

可以定义事件存取器

修饰符 event 委托类型名事件名

{

         add{e+=value;}

         remove{e-=value;}

}

 

事件是一种消息机制

事件源调用事件,别的类注册时间

事件的类型是一个委托

 

4.3Lambda表达式——简洁到极致

泛型(Generic)

List<Book> books= new List<Book>();

Book book =books[0];

 

//以前要用强制类型转换

ArrayList books = new ArrayList();

Book book =(Book) books[0];

 

匿名方法

delegate(参数){方法体}

可以当一个匿名方法

new Thread

new ThreadStart(delegate(){…});

可以被隐式转换为一个兼容的委托类型

new Thread(delegate(){…});

 

Lamda表达式

相当于匿名方法的简写

省略delegate,甚至省略参数类型

直接用(参数)=>{语句或表达式}

button1.Click+=(sender,e)=>{…}

new Thread (()=>{…}).Start();

PlotFun(x=>x*x,0,100);

匿名函数多一个功能:

不写(参数)的匿名函数

可以转成任意多个参数的委托

 

Linq:Language Integrated Query

常见的形式

from c in customers

where c.Age>10

orderby c.Name

select new{c.Name,c.Phone}

相当于

customers

.Where(c=>c.Age>10)

.OrderBy(c=>c.Name)

.Select(c=>new{c.Name,c.Phone})

 

Linq事例

int[] arr= new int[]{8,5,89,3,56,4,1,58};

var m=from n in arr where n<5 orderby nselect n*n;

foreach(var n in m)

{

         Console.WriteLine(n);

}

 

总之

匿名函数使用delegate

Lambda表达式使用=>

Linq使用from,where,select

 

Lambda及相关的写法.txt

 

4.4运算符的重载

使用运算符的例子

this.Location+=new Size(10,10);

TimeSpan diff= date2- date1;

String s1,s2;… if (s1==s2)

运算符有时比方法名更直观

如两个负数用 a+b 比 a.Add(b)更直观

但要慎用

运算符重载有一些限制

如成对,如类型要求,如有的不能重载

 

运算符的声明

一元运算符的声明形式如下

public static 类型 operator 一元运算符(类型 参数名){…}

二院运算符声明的形式如下

public static 类型 operator 二元运算符(类型 参数名,类型 参数名){…}

类型转换运算符声明的形式如下:

public static implicit operator 类型(类型 参数名){…}

public static explicit operator 类型(类型 参数名){…}

复数重载的运算.txt

 

4.5异常处理

异常的概念

C#中的异常处理

try{…}

catch(Exception e){….}

finally{…}

System.Exception类

public Exception();

public Exception(string);

Message属性

StackTrace属性

 

几种常用的异常类

System.OutOfMemoryException

System.StackOverflowException

System.NullReferenceException

System.TypeInitializationException

System.InvalidCastException

System.ArrayTypeMismatchException

System.IndexOutOfRangeException

System.MulticastNotSupportedException

System.ArithmeticException

System.DivideByZeroException

System.OverflowException

 

捕获和处理异常

try{}

catch(AException e1){}

catch(BException e2){}

catch(更一般的Exception e){}

finally{}

注意:catch{}表示捕获所有种类的异常

 

抛出异常

throw语句抛出一个异常的语法为:

throw expression

一般是这样的

if(xxxxxx) throw new SomeException(信息)

 

创建用户自定义异常类

从Exception或ApplicationException继承

重抛异常:throws;

异常链接

throw new Exception (“msg”,e);

这里e称为内部异常

InnerException属性

使得外部进一步知道内部的异常原因

 

算术溢出与checked

对溢出进行检查

对整个程序 csc /checked xxxx.cs

对部分程序

针对表达式:checked(表达式)及unchecked(表达式)

针对快语句:checked{……}及unchecked{….}

对溢出异常进行捕获

try{ }catch( Overflow Exception e){}

 

4.6Attribute

用在类上的

[Serrializable]

public sealed classString:IComparable,Icloneable,IConvertible,Ienumerable

用在方法上的

[STAThread]

static void Main();

 

Attribuete是与类、结构、方法等元素相关的额外信息,时候对元信息的扩展。

通过Attribute可以使程序、甚至语言本身的功能得到增强。

[HelpUrl](http://SomeUrl/ApiDocs/SomeClass)]

class SomeClass

{

         [WebMethod]

         voidGetCustomers(){…}

        

         stringTest([SomeAttr] string param1){…}

}

 

使用Attribute的一般方式

在程序集、类、域、方法等前面用[]表示

可以省略“Attribute”几个字母,只写xxx

可以带参数

         位置参数(相当于构造方法带的参数)

         命名参数(域名或属性名=值)

示例

在Main()方法使用[STAThread]

使用“过时”:AttributeObsolete.cs

使用“条件”:AttributeConditional.cs

在结构上、枚举上使用:StructLayout、Flag

在程序集级别应用Attribute

[assembly:AssemblyCopany(“”)]

 

自定义Attribute

1.声明Attribute类

从System.Attribute继承而来

名字要用xxxAttribute

2.使用Attribute类

在类及成员上面使用方括号

可以省略后缀Attribute

3.通过反射访问属性

 

4.7C#语言中的其他成分

编译预处理

1.标识符声明

#define定义一个标识符

#undef”   取消定义”一个标识符

2.条件处理

#if,#elif,#else,#endif

3.信息报告

#error和#warning

4.行号标记

#line行号”文件名”

 

Unfafe及指针

1.Unsafe

用于修饰、方法

2.fixed及指针

fixed(类型 * 指针名= 表达式)语句

3.sizeof运算符

4.stackallc

在栈上分配的内存,而不是在堆上,因此不会担心内存被垃圾回收器自动回收

 

其他关键字

1.lock

多线程程序中,lock可以将某个对象加锁

 

2.volatile

随时可能被程序以外的其他因素所修改。域被volatile修饰时,会阻止编译器对他的优化

 

4.8程序的组织

名字空间程序的逻辑组织

嵌套类型类中嵌套类型

程序集 程序的物理组织

 

名字空间

1.名字空间的概念

逻辑划分,避免名字冲突

2.名字空间的声明

namespace xxx.xxx{}

3.名字空间的导入

using xxx.xxx

4.使用别名

using 别名= 名字空间或类名

 

嵌套类型

1.嵌套类型的概念

类型中的类型

class A{public class B{public struct C{}}}

new A.B.C();

2.嵌套类型的可访问性

受各个层次的限制

 

程序集

模块

程序集

4.9C#语法的小结

类型声明

类型声明是C#程序的主题,他可以位于名字空间中,也可以是嵌套类型。

类型声明包括以下几种:

1)类class

2)结构 struct

3)接口 interface

4)枚举 enum

5)委托delegate

 

类的成员

1.常数(const)

它代表了与类相关的常数数据。

2.域(field)

它是类中的变量

3.方法(method)

它实现了可以被类实现的计算和行为

4.属性(property)

它定义了命名的属性和与这个属性进行读写相关行为。

5.事件(event)

它定义了由类产生的通知

6.索引(indexer)

它允许类的实例通过与数组相同的方法来索引

7.运算符(operator)

他定义了可以被应用于类的实例上的表达式运算符

8.实例构造函数(instanceconstructor)

它执行需要对类的实例进行初始化的动作

9.析构函数(destructor)

类的实例被清除时实现的动作(结构不能有析构函数)

10.静态构造函数(staticconstructor)

它执行对类本身进行初始化的动作。

11.类型(type)

它代表位于类中的类型

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

子非愚

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值