一 自定义事件

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

  1. // 摘要:
  2.       // 表示定义一组条件并确定指定对象是否符合这些条件的方法。
  3.       //
  4.       // 参数:
  5.       // obj:
  6.       // 要按照由此委托表示的方法中定义的条件进行比较的对象。
  7.       //
  8.       // 类型参数:
  9.       // T:
  10.       // 要比较的对象的类型。
  11.       //
  12.       // 返回结果:
  13.       // 如果 obj 符合由此委托表示的方法中定义的条件,则为 true;否则为 false。
  14.       public delegate bool Predicate<in T>(T obj);
  15.  
  16. 解释:代表有一个输入参数,和返回值为bool类型的函数4.2 Func
    代表可以有多个输入参数和返回值的函数

4.3 Action

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

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

五  基础知识连接

C#编程指南

六 数组抽屉

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

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

  1. int[] arra = new int[] {, , , , , , , , , };
  2.  
  3. var arraySeg = new ArraySegment<int>(arra, , );
  4.  
  5. //取得字数组成员
  6.  
  7. for(int i=arraySeg.Offset;i<arraySeg.Offset+arraySeg.Count;i++)
  8. {
  9. Console.WriteLine(arraySeg.Array[i]);
  10. }

应用方面:所以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<Tuple<string,string,string,int>>();
  3.  
  4. racers.Add(new Tuple<string, string, string, int>("Jacques","Villeneuve","Canada",));
  5. racers.Add(new Tuple<string, string, string, int>("Alan","Jones","Austrlia",));
  6. racers.Add(new Tuple<string, string, string, int>("Jackie","Stewart","United Kingdom",));
  7. racers.Add(new Tuple<string, string, string, int>("Jack","Brabham","Austrlia",));
  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. }

7.4 集

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

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

7.6 NET线程安全集合

Net基础恶补的更多相关文章

  1. Linux回归篇-基础恶补

    前言:  LINUX在之前仅仅了解一些皮毛知识,最近计划深入研究大数据,LINUX当然少不了,所以借此良机将LINUX也顺带添加进入学习的目录之中.为了知识的全面性,本文先恶补一下LINUX的基础,作 ...

  2. jQuery 选择器 (基础恶补之三)+Ajax

    jQuery load() 方法 jQuery load() 方法是简单但强大的 AJAX 方法. load() 方法从服务器加载数据,并把返回的数据放入被选元素中. 语法: $(selector). ...

  3. jQuery 选择器 (基础恶补之二)

    返回 CSS 属性 如需返回指定的 CSS 属性的值,请使用如下语法: css("propertyname"); 下面的例子将返回首个匹配元素的 background-color ...

  4. jQuery 选择器 (基础恶补)

    jQuery 元素选择器 jQuery 使用 CSS 选择器来选取 HTML 元素. $("p") 选取 <p> 元素. $("p.intro") ...

  5. Javascript基础恶补

    1.字符集:Javascript采用Unicode字符集,支持地球上所有在用的语言. 2.区分大小写:Javascript区分大小写,HTML不区分大小写. 3.空格.换行.格式控制符:Javascr ...

  6. Java基础恶补——内存泄露、内存溢出

    http://blog.csdn.net/wisgood/article/details/16818243

  7. [总结帖]Web小白的基础恶补帖

    1. jQuery实现按钮点击跳转网页 <script src="js/jquery/jQuery-2.2.0.min.js" type="text/javascr ...

  8. 第九十六篇:恶补JS基础

    好家伙,来补基础啦,补JS的基础 先来一些概念性的东西 1.什么是JavaScript?  javaScript的简写形式就是JS,一种广泛用于客户端Web开发的脚本语言,常用来给HTML网页添加动态 ...

  9. 从头开始学c++,补基础,补踏实

    在对c++一知半解的情况下,写c++程序是非常吃力的.对于半路出家写c++的我,写了几个颓废的程序后,再也没有勇气用现有的c++知识去写千疮百孔的程序.非常想写出<整洁的代码>中那样的代码 ...

随机推荐

  1. javascript:void(0)的作用示例

    在做页面时,如果想做一个链接点击后不做任何事情,或者响应点击而完成其他事情,可以设置其属性 href = "#",但是,这样会有一个问题,就是当页面有滚动条时,点击后会返回到页面顶 ...

  2. Handler没法取出消息队列中的数据的一个原因

    主线程发送消息到工作线程,工作线程的步骤是固定为3步的. Looper.prepare();//步骤1,线程里使用handler必须这样写, handler = new Handler(){//步骤2 ...

  3. excel列显示形式互换(字母与数字)

    以office2007为例: excel选项>公式>使用公式下的'R1C1引用样式' 打上钩显示形式为数字,不打钩显示形式为字母

  4. django ImageField用法

    settings里的设置 PROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname('__file__'))) MEDIA_ROOT = ...

  5. Flash键盘钢琴谱

    http://hi.baidu.com/%CC%EC%CA%B9%D2%FE%D2%ED/blog/item/e763d4eac3dcfb242cf53468.html <童话>Flash ...

  6. HDU 3336 Count the string KMP

    题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=3336 如果你是ACMer,那么请点击看下 题意:求每一个的前缀在母串中出现次数的总和. AC代码: # ...

  7. (Relax njuptoj)1009 数的计算(DP)

    其实DP 的关键在于找到子问题的结构.  我们规定arr[i][j]为在j左边填写i时的数的个数,很明显:  arr[i][j]=a[0][i]+a[1][i]+...+arr[i/2][i](i&l ...

  8. [转]给Linux系统管理员准备的Nmap命令的29个实用范例+ tsysv 系统服务器管理器

    原文链接:http://os.51cto.com/art/201401/428152.htm Nmap即网络映射器对Linux系统/网络管理员来说是一个开源且非常通用的工具.Nmap用于在远程机器上探 ...

  9. Qt 智能指针学习(7种QT智能指针和4种std智能指针)

    从内存泄露开始? 很简单的入门程序,应该比较熟悉吧 ^_^ #include <QApplication> #include <QLabel> int main(int arg ...

  10. Unix时间戳 POSIX时间 Unix时间

    Unix时间戳(Unix timestamp),或称Unix时间(Unix time).POSIX时间(POSIX time),是一种时间表示方式,定义为从格林威治时间1970年01月01日00时00 ...