C#委托与事件(生动故事)
【委托】
1,工人Peter按工作步骤向老板报告的程序。
程序:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace ConsoleApplication1
{
class Worker
{
Boss boss; public void Advise(Boss boss)
{
this.boss = boss;
} public void DoWork()
{
Console.WriteLine("Worker: work started"); if (this.boss != null)
{
this.boss.WorkStarted();
} Console.WriteLine("Worker: work progressing"); if (this.boss != null)
{
this.boss.WorkProgressing();
} Console.WriteLine("Worker: work completed"); if (this.boss != null)
{
int grade = this.boss.WorkCompleted();
Console.WriteLine("Worker grade = {0}",grade);
}
}
} class Boss
{
public void WorkStarted()
{
//Boss不关心
}
public void WorkProgressing()
{
//Boss不关心
}
public int WorkCompleted()
{
Console.WriteLine("It's about time!");
return 2;
}
}
class Program
{
static void Main(string[] args)
{
Worker peter = new Worker();
Boss boss = new Boss();
peter.Advise(boss);
peter.DoWork(); Console.WriteLine("Main: worker completed work");
Console.ReadLine();
}
}
}
运行结果:
![]()
2,Peter成为名人了,可能会通知整个世界他的工作报告,但必须为整个世界建立一个Advise方法和特殊的回调。因此他决定将可能的通知列表和那些通知方法的实现分离开。采用接口可以解决。
程序:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace ConsoleApplication1
{
class Worker
{
IWorkerEvents events; public void Advise(IWorkerEvents events)
{
this.events = events;
} public void DoWork()
{
Console.WriteLine("Worker: work started"); if (this.events != null)
{
this.events.WorkStarted();
} Console.WriteLine("Worker: work progressing"); if (this.events != null)
{
this.events.WorkProgressing();
} Console.WriteLine("Worker: work completed"); if (this.events != null)
{
int grade = this.events.WorkCompleted();
Console.WriteLine("Worker grade = {0}",grade);
}
}
} interface IWorkerEvents
{
void WorkStarted();
void WorkProgressing();
int WorkCompleted();
} class Boss : IWorkerEvents
{
public void WorkStarted()
{
//Boss不关心
}
public void WorkProgressing()
{
//Boss不关心
}
public int WorkCompleted()
{
Console.WriteLine("It's about time!");
return 2;
}
}
class Program
{
static void Main(string[] args)
{
Worker peter = new Worker();
Boss boss = new Boss();
peter.Advise(boss);
peter.DoWork(); Console.WriteLine("Main: worker completed work");
Console.ReadLine();
}
}
}
运行结果:同上。可见同样的功能实现,结构好多了。
3,通过结构的调整,老板的引用抽象出来并远离他了,这样的话其他人通过实现接口就可以像老板一样可以得到他的工作进度的通知了。但是老板嫌烦了,老板根本不关心WorkStart和WorkProgressing的通知,但每次都要实现接口,麻烦啊。所以结构需要再一次调整,把接口的方法分到单独的委托函数中,其中每个函数都作为一个方法的小的接口。关注delegate语法。
程序:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace ConsoleApplication1
{
delegate void WorkStarted();
delegate void WorkProgressing();
delegate int WorkCompleted(); class Worker
{
public WorkStarted Started;
public WorkProgressing Progressing;
public WorkCompleted Completed; public void DoWork()
{
Console.WriteLine("Worker: work started"); if (this.Started != null)
{
this.Started();
} Console.WriteLine("Worker: work progressing"); if (this.Progressing != null)
{
this.Progressing();
} Console.WriteLine("Worker: work completed"); if (this.Completed != null)
{
int grade = this.Completed();
Console.WriteLine("Worker grade = {0}",grade);
}
}
} class Boss
{
public int WorkCompleted()
{
Console.WriteLine("It's about time!");
return 2;
}
}
class Program
{
static void Main(string[] args)
{
Worker peter = new Worker();
Boss boss = new Boss();
//peter.Completed = new WorkCompleted(boss.WorkCompleted);//委托复杂写法
peter.Completed = boss.WorkCompleted;//委托简单写法
peter.DoWork(); Console.WriteLine("Main: worker completed work");
Console.ReadLine();
}
}
}
运行结果:同上。委托的时候可以采用简单的写法,当然如果不怕麻烦复杂写法也是一样的。
4,老板怕麻烦的问题解决了,但是Peter还没有通知整个世界呢。但整个世界是全方位的实体,将委托挂接到实例成员上似乎不太正确(多个事件的实例需要很多资源)。所以Peter需要将委托挂接到静态成员上。
程序:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace ConsoleApplication1
{
delegate void WorkStarted();
delegate void WorkProgressing();
delegate int WorkCompleted(); class Worker
{
public WorkStarted Started;
public WorkProgressing Progressing;
public WorkCompleted Completed; public void DoWork()
{
Console.WriteLine("Worker: work started"); if (this.Started != null)
{
this.Started();
} Console.WriteLine("Worker: work progressing"); if (this.Progressing != null)
{
this.Progressing();
} Console.WriteLine("Worker: work completed"); if (this.Completed != null)
{
int grade = this.Completed();
Console.WriteLine("Worker grade = {0}",grade);
}
}
} class Boss
{
public int WorkCompleted()
{
Console.WriteLine("It's about time!");
return 2;
}
} class Universe
{
public static void WorkerStartedWork()
{
Console.WriteLine("Universe notices with worker's work");
}
public static int WorkerCompletedWork()
{
Console.WriteLine("Universe pleased with worker's work");
return 10;
}
} class Program
{
static void Main(string[] args)
{
Worker peter = new Worker();
Boss boss = new Boss();
//peter.Completed = new WorkCompleted(boss.WorkCompleted);//委托复杂写法
peter.Completed = boss.WorkCompleted;//委托简单写法 peter.Started = Universe.WorkerStartedWork;
peter.Completed = Universe.WorkerCompletedWork; //给老板的委托给覆盖了 peter.DoWork(); Console.WriteLine("Main: worker completed work");
Console.ReadLine();
}
}
}
运行结果:
![]()
5,问题都解决了吧,但是世界很忙啊,不习惯关注但个人,它希望将Peter的老板的委托替换成他自己的,这时在Peter的Worker类中公开委托字段的一个无意识的副作用。同样的,如果Peter的老板不耐烦了,他也会自己决定炒掉Peter的委托。但Peter不希望自己去实现这些函数,他使用了event关键字让C#编译器来为他生成这些方法。
代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace ConsoleApplication1
{
delegate void WorkStarted();
delegate void WorkProgressing();
delegate int WorkCompleted(); class Worker
{
public event WorkStarted Started;
public event WorkProgressing Progressing;
public event WorkCompleted Completed; public void DoWork()
{
Console.WriteLine("Worker: work started"); if (this.Started != null)
{
this.Started();
} Console.WriteLine("Worker: work progressing"); if (this.Progressing != null)
{
this.Progressing();
} Console.WriteLine("Worker: work completed"); if (this.Completed != null)
{
int grade = this.Completed();
Console.WriteLine("Worker grade = {0}",grade);
}
}
} class Boss
{
public int WorkCompleted()
{
Console.WriteLine("It's about time!");
return 2;
}
} class Universe
{
public static void WorkerStartedWork()
{
Console.WriteLine("Universe notices with worker's work");
}
public static int WorkerCompletedWork()
{
Console.WriteLine("Universe pleased with worker's work");
return 10;
}
} class Program
{
static void Main(string[] args)
{
Worker peter = new Worker();
Boss boss = new Boss(); peter.Completed += boss.WorkCompleted;//注意区别 += peter.Started += Universe.WorkerStartedWork;
peter.Completed += Universe.WorkerCompletedWork; peter.DoWork(); Console.WriteLine("Main: worker completed work");
Console.ReadLine();
}
}
}
运行结果:
![]()
可见老板和全世界都通知到了哦!
6,到现在为止,所有监听者的需求都满足了,而且也不需要与特定的实现紧密的耦合。但他发现虽然老板和全世界都通知到了,但他只得到了其中一个的评分。他希望每个得分都能被反馈回来。所以,他进入他的委托,将监听者列表拉出来,并手工地调用全部监听者。
代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace ConsoleApplication1
{
delegate void WorkStarted();
delegate void WorkProgressing();
delegate int WorkCompleted(); class Worker
{
public event WorkStarted Started;
public event WorkProgressing Progressing;
public event WorkCompleted Completed; public void DoWork()
{
Console.WriteLine("Worker: work started"); if (this.Started != null)
{
this.Started();
} Console.WriteLine("Worker: work progressing"); if (this.Progressing != null)
{
this.Progressing();
} Console.WriteLine("Worker: work completed"); if (this.Completed != null)
{
foreach (WorkCompleted wc in this.Completed.GetInvocationList()) //注意这里
{
int grade = wc();
Console.WriteLine("Worker grade = {0}",grade);
} }
}
} class Boss
{
public int WorkCompleted()
{
Console.WriteLine("It's about time!");
return 2;
}
} class Universe
{
public static void WorkerStartedWork()
{
Console.WriteLine("Universe notices with worker's work");
}
public static int WorkerCompletedWork()
{
Console.WriteLine("Universe pleased with worker's work");
return 10;
}
} class Program
{
static void Main(string[] args)
{
Worker peter = new Worker();
Boss boss = new Boss(); peter.Completed += boss.WorkCompleted;//注意区别 += peter.Started += Universe.WorkerStartedWork;
peter.Completed += Universe.WorkerCompletedWork; peter.DoWork(); Console.WriteLine("Main: worker completed work");
Console.ReadLine();
}
}
}
运行结果:
![]()
这样就捕获了所有的结果。
7,新的问题产生了,老板和世界都很忙,也都有自己的事情要做,当Peter主动要求反馈是还要等他们忙完手上的事情才能,这时Peter只能等待。
代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace ConsoleApplication1
{
delegate void WorkStarted();
delegate void WorkProgressing();
delegate int WorkCompleted(); class Worker
{
public event WorkStarted Started;
public event WorkProgressing Progressing;
public event WorkCompleted Completed; public void DoWork()
{
Console.WriteLine("Worker: work started"); if (this.Started != null)
{
this.Started();
} Console.WriteLine("Worker: work progressing"); if (this.Progressing != null)
{
this.Progressing();
} Console.WriteLine("Worker: work completed"); if (this.Completed != null)
{
foreach (WorkCompleted wc in this.Completed.GetInvocationList()) //注意这里
{
int grade = wc();
Console.WriteLine("Worker grade = {0}",grade);
} }
}
} class Boss
{
public int WorkCompleted()
{
System.Threading.Thread.Sleep(5000);//模拟老板正在忙着做的事情
Console.WriteLine("It's about time!");
return 2;
}
} class Universe
{
public static void WorkerStartedWork()
{
Console.WriteLine("Universe notices with worker's work");
}
public static int WorkerCompletedWork()
{
System.Threading.Thread.Sleep(10000); //模拟世界正在忙着做的事情
Console.WriteLine("Universe pleased with worker's work");
return 10;
}
} class Program
{
static void Main(string[] args)
{
Worker peter = new Worker();
Boss boss = new Boss(); peter.Completed += boss.WorkCompleted;//注意区别 += peter.Started += Universe.WorkerStartedWork;
peter.Completed += Universe.WorkerCompletedWork; peter.DoWork(); Console.WriteLine("Main: worker completed work");
Console.ReadLine();
}
}
}
运行结果:
等待老板的打分用了5秒钟,等待世界打分用了10秒钟(共计15秒),输出结果如上例所示。可见效率并不高啊,Peter的其他工作地时间,都用来等待打分了,老板不满意了。你等我干什么啊,我忙着呢,打好告诉你。
8,Peter想,老子等个P打分啊,爱打不打,我干我的。(索性不要打分了)
代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace ConsoleApplication1
{
delegate void WorkStarted();
delegate void WorkProgressing();
delegate int WorkCompleted(); class Worker
{
public event WorkStarted Started;
public event WorkProgressing Progressing;
public event WorkCompleted Completed; public void DoWork()
{
Console.WriteLine("Worker: work started"); if (this.Started != null)
{
this.Started();
} Console.WriteLine("Worker: work progressing"); if (this.Progressing != null)
{
this.Progressing();
} Console.WriteLine("Worker: work completed"); if (this.Completed != null)
{
foreach (WorkCompleted wc in this.Completed.GetInvocationList()) //注意这里
{
//int grade = wc();
//Console.WriteLine("Worker grade = {0}",grade);
wc.BeginInvoke(null, null); //异步通知
} }
}
} class Boss
{
public int WorkCompleted()
{
System.Threading.Thread.Sleep(5000);//模拟老板正在忙着做的事情
Console.WriteLine("It's about time!");
return 2;
}
} class Universe
{
public static void WorkerStartedWork()
{
Console.WriteLine("Universe notices with worker's work");
}
public static int WorkerCompletedWork()
{
System.Threading.Thread.Sleep(10000); //模拟世界正在忙着做的事情
Console.WriteLine("Universe pleased with worker's work");
return 10;
}
} class Program
{
static void Main(string[] args)
{
Worker peter = new Worker();
Boss boss = new Boss(); peter.Completed += boss.WorkCompleted;//注意区别 += peter.Started += Universe.WorkerStartedWork;
peter.Completed += Universe.WorkerCompletedWork; peter.DoWork(); Console.WriteLine("Main: worker completed work");
Console.ReadLine();
}
}
}
运行结果:
![]()
Peter通知老板和世界之后马上干别的了,而老板和世界自己处理好自己的事情得到了这个通知,老板用时(5秒),世界用时(10秒),由于是并行,所以共计10秒。老板和世界都对Peter打了分,但Peter此时并不关心这些,老板发怒了,我给你打分你不理我,你还想不想干了?
9,调用BeginInvoke方法允许Peter通知监听者,同时让Peter可以立即回去工作,让进程的线程池去调用委托。这里他采用轮询的方式来获得评分。
代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace ConsoleApplication1
{
delegate void WorkStarted();
delegate void WorkProgressing();
delegate int WorkCompleted(); class Worker
{
public event WorkStarted Started;
public event WorkProgressing Progressing;
public event WorkCompleted Completed; public void DoWork()
{
Console.WriteLine("Worker: work started"); if (this.Started != null)
{
this.Started();
} Console.WriteLine("Worker: work progressing"); if (this.Progressing != null)
{
this.Progressing();
} Console.WriteLine("Worker: work completed"); if (this.Completed != null)
{
foreach (WorkCompleted wc in this.Completed.GetInvocationList()) //注意这里
{
//int grade = wc();
//Console.WriteLine("Worker grade = {0}",grade);
//wc.BeginInvoke(null, null); //异步通知 IAsyncResult result = wc.BeginInvoke(null, null);
while (!result.IsCompleted)
{
System.Threading.Thread.Sleep(1);
}
int grade = wc.EndInvoke(result);
Console.WriteLine("Worker grade = {0}",grade); } }
}
} class Boss
{
public int WorkCompleted()
{
System.Threading.Thread.Sleep(5000);//模拟老板正在忙着做的事情
Console.WriteLine("It's about time!");
return 2;
}
} class Universe
{
public static void WorkerStartedWork()
{
Console.WriteLine("Universe notices with worker's work");
}
public static int WorkerCompletedWork()
{
System.Threading.Thread.Sleep(10000); //模拟世界正在忙着做的事情
Console.WriteLine("Universe pleased with worker's work");
return 10;
}
} class Program
{
static void Main(string[] args)
{
Worker peter = new Worker();
Boss boss = new Boss(); peter.Completed += boss.WorkCompleted;//注意区别 += peter.Started += Universe.WorkerStartedWork;
peter.Completed += Universe.WorkerCompletedWork; peter.DoWork(); Console.WriteLine("Main: worker completed work");
Console.ReadLine();
}
}
}
运行结果:
![]()
10,不幸的是,Peter回到了开头,他不希望他的老板做的事情,在实体工作时候监视实体。更重要的是,轮询也占用工作时间啊,可以看到Main函数的返回位置就知道了。所以Peter决定用他自己的委托作为在异步操作结束时获得的方法,这允许他立即回去工作,但他的工作仍然可以获得通知。
代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace ConsoleApplication1
{
delegate void WorkStarted();
delegate void WorkProgressing();
delegate int WorkCompleted(); class Worker
{
public event WorkStarted Started;
public event WorkProgressing Progressing;
public event WorkCompleted Completed; public void DoWork()
{
Console.WriteLine("Worker: work started"); if (this.Started != null)
{
this.Started();
} Console.WriteLine("Worker: work progressing"); if (this.Progressing != null)
{
this.Progressing();
} Console.WriteLine("Worker: work completed"); if (this.Completed != null)
{
foreach (WorkCompleted wc in this.Completed.GetInvocationList()) //注意这里
{
wc.BeginInvoke(this.WorkGraded,wc); //注意参数
} }
} void WorkGraded(IAsyncResult result) //委托
{
WorkCompleted wc = (WorkCompleted)result.AsyncState;
int grade = wc.EndInvoke(result);
Console.WriteLine("Worker grade = {0}", grade);
}
} class Boss
{
public int WorkCompleted()
{
System.Threading.Thread.Sleep(5000);//模拟老板正在忙着做的事情
Console.WriteLine("It's about time!");
return 2;
}
} class Universe
{
public static void WorkerStartedWork()
{
Console.WriteLine("Universe notices with worker's work");
}
public static int WorkerCompletedWork()
{
System.Threading.Thread.Sleep(10000); //模拟世界正在忙着做的事情
Console.WriteLine("Universe pleased with worker's work");
return 10;
}
} class Program
{
static void Main(string[] args)
{
Worker peter = new Worker();
Boss boss = new Boss(); peter.Completed += boss.WorkCompleted;//注意区别 += peter.Started += Universe.WorkerStartedWork;
peter.Completed += Universe.WorkerCompletedWork; peter.DoWork(); Console.WriteLine("Main: worker completed work");
Console.ReadLine();
}
}
}
运行结果:
![]()
通过查看Main发出的信息可以得知,Peter确实可以不用为返回评分的事情分心了。
11,功能完成的实现了,但仔细分析程序结构,发现WorkGraded方法没什么好的理由让他单独存在。Peter可以将处理工作地评分的过程所需的代码放进一个匿名委托中。
代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace ConsoleApplication1
{
delegate void WorkStarted();
delegate void WorkProgressing();
delegate int WorkCompleted(); class Worker
{
public event WorkStarted Started;
public event WorkProgressing Progressing;
public event WorkCompleted Completed; public void DoWork()
{
Console.WriteLine("Worker: work started"); if (this.Started != null)
{a
this.Started();
} Console.WriteLine("Worker: work progressing"); if (this.Progressing != null)
{
this.Progressing();
} Console.WriteLine("Worker: work completed"); if (this.Completed != null)
{
foreach (WorkCompleted wc in this.Completed.GetInvocationList()) //注意这里
{
WorkCompleted wc2 = wc; //wc会发生变化,应取其副本
wc.BeginInvoke(delegate(IAsyncResult result) //匿名委托的格式
{
int grade = wc2.EndInvoke(result);
Console.WriteLine("Worker grade = {0}", grade);
},null);
} }
}
} class Boss
{
public int WorkCompleted()
{
System.Threading.Thread.Sleep(5000);//模拟老板正在忙着做的事情
Console.WriteLine("It's about time!");
return 2;
}
} class Universe
{
public static void WorkerStartedWork()
{
Console.WriteLine("Universe notices with worker's work");
}
public static int WorkerCompletedWork()
{
System.Threading.Thread.Sleep(10000); //模拟世界正在忙着做的事情
Console.WriteLine("Universe pleased with worker's work");
return 10;
}
} class Program
{
static void Main(string[] args)
{
Worker peter = new Worker();
Boss boss = new Boss(); peter.Completed += boss.WorkCompleted;//注意区别 += peter.Started += Universe.WorkerStartedWork;
peter.Completed += Universe.WorkerCompletedWork; peter.DoWork(); Console.WriteLine("Main: worker completed work");
Console.ReadLine();
}
}
}
运行结果:如上例所示。至此,整个功能与结构都完美了。
C#委托与事件(生动故事)的更多相关文章
- 转载: jQuery事件委托( bind() \ live() \ delegate()) [委托 和 绑定的故事]
转载:http://blog.csdn.net/zc2087/article/details/7287429 随着DOM结构的复杂化和Ajax等动态脚本技术的运用,事件委托自然浮出了水面.jQuery ...
- .NET面试题系列[7] - 委托与事件
委托和事件 委托在C#中具有无比重要的地位. C#中的委托可以说俯拾即是,从LINQ中的lambda表达式到(包括但不限于)winform,wpf中的各种事件都有着委托的身影.C#中如果没有了事件,那 ...
- C#委托与事件的简单使用
前言:上一篇博文从原理和定义的角度介绍了C#的委托和事件.本文通过一个简单的小故事,来说明C#委托与事件的使用方法及其方便之处. 在阅读本文之前,需要你对委托和事件的基本概念有所了解.如果你是初次接触 ...
- [转]大白话系列之C#委托与事件讲解(三)
本文转自:http://www.cnblogs.com/wudiwushen/archive/2010/04/21/1717378.html [我希望大家在看完文章的时候,多做做练习,自己也可以想个场 ...
- 不知道的陷阱:C#委托和事件的困惑
转载网址:http://www.cnblogs.com/buptzym/archive/2013/03/15/2962300.html 不知道的陷阱:C#委托和事件的困惑 一. 问题引入 通常,一 ...
- C#委托与事件总结
目录 C#委托与事件的总结 1.概述 2.委托 2.1 什么是委托 2.2 委託的使用 2.3 深入理解委托 2.4 为什么要使用委托 2.5 代码清单 3.事件 3.1 事件与委托的关系 3.2 订 ...
- 【详细】【转】C#中理解委托和事件 事件的本质其实就是委托 RabbitMQ英汉互翼(一),RabbitMQ, RabbitMQ教程, RabbitMQ入门
[详细][转]C#中理解委托和事件 文章是很基础,但很实用,看了这篇文章,让我一下回到了2016年刚刚学委托的时候,故转之! 1.委托 委托类似于C++中的函数指针(一个指向内存位置的指针).委托 ...
- .NET基础拾遗(4)委托、事件、反射与特性
Index : (1)类型语法.内存管理和垃圾回收基础 (2)面向对象的实现和异常的处理基础 (3)字符串.集合与流 (4)委托.事件.反射与特性 (5)多线程开发基础 (6)ADO.NET与数据库开 ...
- [转载]C#深入分析委托与事件
原文出处: 作者:风尘浪子 原文链接:http://www.cnblogs.com/leslies2/archive/2012/03/22/2389318.html 同类链接:http://www.c ...
- [转载]C#委托和事件(Delegate、Event、EventHandler、EventArgs)
原文链接:http://blog.csdn.net/zwj7612356/article/details/8272520 14.1.委托 当要把方法作为实参传送给其他方法的形参时,形参需要使用委托.委 ...
随机推荐
- Vert.x,一个异步、可伸缩、并发应用框架引发的思考
2012年听说过Vert.x这个框架之后,去年大致了解了下,最近开始进一步熟悉这个框架. Vert.x是一个用于下一代异步.可伸缩.并发应用的框架,旨在为JVM提供一个Node.js的替代方案.开发者 ...
- centos下安装redis/mysql等基础环境
1.修改语言 阿里云的ECS默认语言是:en_US.UTF-8,需要改成zh_CN.UTF-8 修改方法:vim /etc/locale.conf,然后重启. 查看方法:echo $LANG 2.安装 ...
- [Python] Generates permutations
>>> import itertools >>> for p in itertools.permutations('ABCD'): ... print(p) ('A ...
- (七十一)关于UITableView退出崩溃的问题和滚动究竟部的方法
[TableView退出崩溃的问题] 近期在使用TableView时偶然发如今TableView中数据较多时,假设在滚动过程中退出TableView到上一界面.会引起程序的崩溃.经过网上查阅和思考我发 ...
- UVA 12508 - Triangles in the Grid(计数问题)
12508 - Triangles in the Grid 题目链接 题意:给定一个n∗m格子的矩阵,然后给定A,B.问能找到几个面积在A到B之间的三角形. 思路:枚举每一个子矩阵,然后求[0,A]的 ...
- poi excel自己主动转换成javabean 支持引用类型属性二级转换
近期项目须要使用excel导入功能.导入学生的时候须要指定所在班级,使用excel一次性导入! 将曾经的代码改改支持属性内引用类的转换. 測试对象为User对象,javabean结构: private ...
- web api 特点
webapi有很多特点(我不想用优点这个词),比如说restful,支持路由,简单,类似mvc controller/action的代码编写方式,灵活的托管方式,和web的集成等等. Web API的 ...
- [C++11] 默认构造函数
类通过一个特殊的构造函数来控制默认初始化过程.这个函数就是默认构造函数.默认构造函数无需不论什么实參. 我们能够显示的定义默认构造函数也能够让编译器为我们生成默认构造函数. 默认构造函数以例如以下规则 ...
- iOS动画之模拟音量振动条
音量振动条 效果图: 假设实现? 创建3个layer.按顺序播放y轴缩放动画 利用CAReplicatorLayer实现 1.什么是CAReplicatorLayer? 一种能够复制自己子层的laye ...
- Android学习笔记进阶十二之裁截图片
package xiaosi.cut; import java.io.File; import android.app.Activity; import android.content.Intent; ...