博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Net基础恶补
阅读量:4564 次
发布时间:2019-06-08

本文共 3957 字,大约阅读时间需要 13 分钟。

一 自定义事件

1 之前一直都是使用事件调用来触发事件,看代码

// 定义一个事件

public event EventHandler;

//触发事件

public void OnEvent(){

  if(EventHandler!=null){

    EventHandler(this,EventArgs.Empty);

  ]

}

//使用事件

EventHandler+=EventHandlerMethod(o,e);

 

2 另外一种方式,虽然见了很多次了,但是因为少用就一直看着能理解但是自己基本使用

 

private Action evenAction;

 

// 定义事件

 

public event Action ActionEvent

{
  add { evenAction += value; }
  remove { evenAction -= value; }
}

//使用事件

evenAction+=EventHandlerMethod();

 

//触发事件

public void ExecutEvent()

{
  if(evenAction!=null)
  evenAction();
}

 

3 对比总结

除了在写法上表现为不太相同之外没发现有什么明显的区别

 

二 net闭包

 

原来net也有闭包的情况

var list = new List<Action>();

for (int i = 0; i < 10; i++)
{
list.Add(()=>
Console.WriteLine(i.ToString()));
}

list.ForEach(x=>x());

 

运行结果全是10,为啥,为啥

原来的从net形式参数传值和真正调用说起,对于栈变量传递的形式参数本质上是复制一份副本,而引用类型则是传递的指针,而对于int类型的i来说,只有在真正发生调用的时候才会将外来的参数复制一份副本

然后交给形式变量,所以在真正执行的时候才会真正传递形式变量,也就是复制副本,前面的过程仅仅是一份引用而已,到了真正调用的时候i的值已经变化为10了,传入的参数自然而然也就是10;

那么怎么避免呢?

var list = new List<Action>();

for (int i = 0; i < 10; i++)
{
int c = i;
list.Add(()=>
Console.WriteLine(c.ToString()));
}

list.ForEach(x=>x());

让他在调用之前就复制一次副本,调用的参数引用这份副本,真正调用的时候在复制一次到形式变量,也就对了

 

三 多元组Tuple 

  一般定义数组我们多用list或者直接使用 类型[]  的方式定义

比如:定义一维数组

var listArrat=new List<T>();

int[] intArr =new int[4];

 

定义二维数组

var dic=new Dictory<string,string>();

int[][] intArr = new int[4][];

 

有没有发现如果维数越高越来越复杂,且直接定义的数组有[]下标运算访问索引超界的危险,于是就有了Tuple的出现,Tuple是一个泛型类,意味着兼容任何类型,且最高可直接提供8维数组,且最后一个元也可以是Tuple,这就构成了Tuple嵌套,意味着维数几乎不限制,我们来看看示例;

public class Point

{
public int X { get; set; }
public int Y { get; set; }
}

//the user customer data type.
Point p = new Point() { X = 10, Y = 20 };
//use the predefine generic tuple type.
Tuple<int, int> p2 = new Tuple<int, int>(10, 20);
//
Console.WriteLine(p.X + p.Y);
Console.WriteLine(p2.Item1 + p2.Item2);//item1,item2按照低维向高维访问,如二维数组先x,后y,如果是三维那么自然也是xyz的顺序,这样看起来是不是很方便,可以在一些临时数据封装上有着方便的使用

Tuple常使用于函数有多个返回值,从而替代了直接传递指针的ref和out形式参数

 四  泛型代理

 

4.1 Predicate

// 摘要:          //     表示定义一组条件并确定指定对象是否符合这些条件的方法。          //          // 参数:          //   obj:          //     要按照由此委托表示的方法中定义的条件进行比较的对象。          //          // 类型参数:          //   T:          //     要比较的对象的类型。          //          // 返回结果:          //     如果 obj 符合由此委托表示的方法中定义的条件,则为 true;否则为 false。          public delegate bool Predicate
(T obj); 解释:代表有一个输入参数,和返回值为bool类型的函数4.2 Func 代表可以有多个输入参数和返回值的函数

 

 4.3 Action

代表有多个输入参数但是没有返回值

 

 

Action用于参数输入,或者空参数的代理,Func用于参数输入和有返回值的代理

 五  基础知识连接

 

六 数组抽屉

ArraySegment<T>对数组一层包装,可以很快获取数组中成员,也就是很方面访问数组中某段子成员,看提供的API

举个例子:比如我现在有一个数组a,大小为10的长度,我现在只想操作从第5个元素开始,长度为3的这段,按照自己的实现我们必须对该数组进行循环,但是现在有了ArraySegment数组抽屉已经为我们包装了好API,用代码说明

1 int[] arra = new int[] {
1, 4, 5, 11, 13, 14, 15, 18, 10, 20}; 2 3 var arraySeg = new ArraySegment
(arra, 5, 3); 4 5 //取得字数组成员 6 7 for(int i=arraySeg.Offset;i

 

应用方面:所以ArraySegment可以用在内存碎片(fragmentation)较多的地方,来减少内存碎片的产生,以便使内存更有序,提高我们的程序性能。比如Socket.BeginReceive异步接收频繁的时候,我们并不知道要接受的这个buffer长度,所以就预先设置一个固定值,这时候这块内存就会被pin住,一直等到网络硬件接收到数据完成为止,这往往比较容易产生碎片,

 

 

七 集合

7.1 有序列表

SortedList<>泛型

7.2 有序字典

SortedDictionary<>

7.3 LookUp

LookUp相当于对一个实现了IEnumerable<>的集合进行分组

LookUp<TKey,TElement>其中Temelent是一个列表,LookUp是实现了IEnumerable接口的扩展方法

举个例子

1  //选手集合 2                 var racers = new List
>(); 3 4 racers.Add(new Tuple
("Jacques","Villeneuve","Canada",11)); 5 racers.Add(new Tuple
("Alan","Jones","Austrlia",12)); 6 racers.Add(new Tuple
("Jackie","Stewart","United Kingdom",13)); 7 racers.Add(new Tuple
("Jack","Brabham","Austrlia",14)); 8 9 // 根据Item3 即国家进行分组10 var lookupRacers = racers.ToLookup(x => x.Item3);11 12 //取出澳大利亚 这组来循环其子元素13 foreach (var r in lookupRacers["Austrlia"])14 {15 Console.WriteLine(r.Item1);16 }
View Code

 

7.4 集

HashSet不重复的哈希列表,SortedSet不重复的有序列表

7.5 NET提供泛型集合性能对比

 

 

 

7.6 NET线程安全集合

 

转载于:https://www.cnblogs.com/rjjs/p/5613469.html

你可能感兴趣的文章
[html][javascript]父子窗体传值
查看>>
收房细则
查看>>
读《Android深度探索(卷1)HAL与驱动开发》的一些思考10
查看>>
二十三、uevnet机制和U盘自动挂载
查看>>
Kettle 提取mongodb最大编号
查看>>
Vue2.0-token权限处理
查看>>
Caffeine缓存
查看>>
JavaScript 回车键转成Tab键
查看>>
CentOS7配置MySQL5.7主备
查看>>
合并区间(LintCode)
查看>>
mysql索引的创建
查看>>
《 BCG 原创 :系列 三》 添加菜单栏
查看>>
Java中关于CyclicBarrier的使用
查看>>
vsftpd配置教程
查看>>
first ios app
查看>>
论javascript模块化的优缺
查看>>
css 冷门样式大全
查看>>
MYSQL 服务无法启动,错误日志:InnoDB: .\ibdata1 must be writable
查看>>
Java并发包基石-AQS详解
查看>>
Stopwatch运行时间 Parallel并行任务
查看>>