第十六天:
(开始学习C#已经过了半个月了,还真是漫长啊~)
8.2.4 Action<T>和Func<T>委托
除了为每个参数和返回类型定义的一个新委托类型之外,还可以使用Action<T>和Func<T>委托
泛型Action<T>委托表示引用一个void返回类型的方法。这个委托类存在不同的变体,可以传递至多16种不同的参数类型。
没有泛型参数的Action类可调用没有参数的方法。
Action<in T>调用带一个参数的方法……
Func<T>委托类似,但允许调用带返回类型的方法。
Func<out TResult>委托类型号可调用带返回类型且无参数的方法。
Func<in T,out TResult>调用一个参数的方法。
使用:
之前那个delegate double DoubleOp(double x);
现在直接这样用:
Func<double,double>[] operations={
MathOperations.MultiplyByTwo,
MathOperations.Square
}
传参数时也是Func<double,double> action
8.2.5 BubbleSorter示例
冒泡排序,Sort()方法能给任何对象排序:
class BubbleSorter{
static public void Sort<T>(IList<T> sortArray,Func<T,T,bool> comparison){
bool swapped=true;
do{
swapped=false;
for(int i=0;i<sortArray.Count-1;i++){
if(comparison(sortArray[i+1],sortArray[i])){
T temp=sortArray[i];
sortArray[i]=sortArray[i+1];
sortArray[i+1]=T;
swapped=true;
}
}
}while(swapped);
}
}
class Employee{
public Employee(string name,decimal salary){
this.Name=name;
this.Salary=salary;
}
public string Name(get;private set;)
public decimal Salary{get;private set;}
public override string ToString(){
return string.Format("{0},{1:C}",Name,Salary);
}
public static bool CompareSalary(Employee e1,Employee e2){
return e1.Salary<e2.Salary;
}
}
using System;
namespace B{
class Program{
static void Main(){
Employee[] employees={
new Employee("Bugs Bunny",20000),
new Employee("Elmer Fudd",10000),
new Employee("Daffy Duck",25000),
new Employee("Wile Coyote",1000000.38m),
new Employee("Foghorn Leghorn",23000),
new Employee("RoadRunner",50000)
};
BubbleSorter.Sort(employees,Employee.CompareSalary);
foreach(var employee in employees){
Console.WriteLine(employee);
}
}
}
}
8.2.6多播委托
委托也可以包含多个方法,这种委托称为多播委托。如果调用多播委托,就可以按顺序连续调用多个方法。为此,委托的签名就必须返回void,否则,就只能得到委托调用的最后一个方法的结果。
例:
class program{
static void Main(){
Action<double> operations=MathOperations.MultiplyByTwo;
operations+=MathOperations.Square;
因为要存储两个方法的引用,所以实例化了一个委托数组。而这里只是在同一个多播委托中添加两个操作,多播委托可以识别运算符"+"和"+="
扩展:
Action<double> operation1=MathOperations.MultiplyByTwo;
Action<double> operation2=MathOperations.Square;
Action<double> operation3=operation1+operation2;
例:
重新写:
class MathOperations{
public static void MultiplyByTwo(double value){
double result=value*2;
Console.WriteLine("Multiplying by 2:{0} gives {1}",value,result);
}
public static void Square(double value){
double result=value*value;
Console.WriteLine("Squaring:{0} gives {1}",value,result);
}
}
重新写:
static void ProcessAndDisplayNumber(Action<double> value,double value){
Console.WriteLine();
Console.WriteLine("ProcessAndDisplayNumber called with value = {0}",value);
action(value);
}
多播委托:
static void Main(){
Action<double> operation=MathOperations.MultiplyByTwo;
operations+=MathOperations.Square;
ProcessAndDisplayNumber(operation,2.0);
ProcessAndDisplayNumber(operation,7.94);
processAndDisplayNumber(operation,1.414);
Console.WriteLine();
}
//输出略
多播委托包括一个逐个调用的委托集合,如果通过委托调用的其中一个方法抛出异常州,整个迭代就会停止。
其它略
8.2.7 匿名方法
到目前为止,要想使委托工作,方法必须已经存在(即委托是用它将调用的方法的相同签名定义的)。
但还有另外一种使用委托的方法,即通过匿名方法,匿名方法是用作委托的参数的一段代码。
例:
using System;
namespace W{
class Program{
static void Main(){
string mid=", middle part,";
Func<string string> anonDel=delegate(string param){
param+=mid;
param+=" and this was added to the string.";
return param;
}
Console.WriteLine(anonDel("Start of string"));
}
}
}
//注:令我想起了js
(2014.12.18)
(开始学习C#已经过了半个月了,还真是漫长啊~)
8.2.4 Action<T>和Func<T>委托
除了为每个参数和返回类型定义的一个新委托类型之外,还可以使用Action<T>和Func<T>委托
泛型Action<T>委托表示引用一个void返回类型的方法。这个委托类存在不同的变体,可以传递至多16种不同的参数类型。
没有泛型参数的Action类可调用没有参数的方法。
Action<in T>调用带一个参数的方法……
Func<T>委托类似,但允许调用带返回类型的方法。
Func<out TResult>委托类型号可调用带返回类型且无参数的方法。
Func<in T,out TResult>调用一个参数的方法。
使用:
之前那个delegate double DoubleOp(double x);
现在直接这样用:
Func<double,double>[] operations={
MathOperations.MultiplyByTwo,
MathOperations.Square
}
传参数时也是Func<double,double> action
8.2.5 BubbleSorter示例
冒泡排序,Sort()方法能给任何对象排序:
class BubbleSorter{
static public void Sort<T>(IList<T> sortArray,Func<T,T,bool> comparison){
bool swapped=true;
do{
swapped=false;
for(int i=0;i<sortArray.Count-1;i++){
if(comparison(sortArray[i+1],sortArray[i])){
T temp=sortArray[i];
sortArray[i]=sortArray[i+1];
sortArray[i+1]=T;
swapped=true;
}
}
}while(swapped);
}
}
class Employee{
public Employee(string name,decimal salary){
this.Name=name;
this.Salary=salary;
}
public string Name(get;private set;)
public decimal Salary{get;private set;}
public override string ToString(){
return string.Format("{0},{1:C}",Name,Salary);
}
public static bool CompareSalary(Employee e1,Employee e2){
return e1.Salary<e2.Salary;
}
}
using System;
namespace B{
class Program{
static void Main(){
Employee[] employees={
new Employee("Bugs Bunny",20000),
new Employee("Elmer Fudd",10000),
new Employee("Daffy Duck",25000),
new Employee("Wile Coyote",1000000.38m),
new Employee("Foghorn Leghorn",23000),
new Employee("RoadRunner",50000)
};
BubbleSorter.Sort(employees,Employee.CompareSalary);
foreach(var employee in employees){
Console.WriteLine(employee);
}
}
}
}
8.2.6多播委托
委托也可以包含多个方法,这种委托称为多播委托。如果调用多播委托,就可以按顺序连续调用多个方法。为此,委托的签名就必须返回void,否则,就只能得到委托调用的最后一个方法的结果。
例:
class program{
static void Main(){
Action<double> operations=MathOperations.MultiplyByTwo;
operations+=MathOperations.Square;
因为要存储两个方法的引用,所以实例化了一个委托数组。而这里只是在同一个多播委托中添加两个操作,多播委托可以识别运算符"+"和"+="
扩展:
Action<double> operation1=MathOperations.MultiplyByTwo;
Action<double> operation2=MathOperations.Square;
Action<double> operation3=operation1+operation2;
例:
重新写:
class MathOperations{
public static void MultiplyByTwo(double value){
double result=value*2;
Console.WriteLine("Multiplying by 2:{0} gives {1}",value,result);
}
public static void Square(double value){
double result=value*value;
Console.WriteLine("Squaring:{0} gives {1}",value,result);
}
}
重新写:
static void ProcessAndDisplayNumber(Action<double> value,double value){
Console.WriteLine();
Console.WriteLine("ProcessAndDisplayNumber called with value = {0}",value);
action(value);
}
多播委托:
static void Main(){
Action<double> operation=MathOperations.MultiplyByTwo;
operations+=MathOperations.Square;
ProcessAndDisplayNumber(operation,2.0);
ProcessAndDisplayNumber(operation,7.94);
processAndDisplayNumber(operation,1.414);
Console.WriteLine();
}
//输出略
多播委托包括一个逐个调用的委托集合,如果通过委托调用的其中一个方法抛出异常州,整个迭代就会停止。
其它略
8.2.7 匿名方法
到目前为止,要想使委托工作,方法必须已经存在(即委托是用它将调用的方法的相同签名定义的)。
但还有另外一种使用委托的方法,即通过匿名方法,匿名方法是用作委托的参数的一段代码。
例:
using System;
namespace W{
class Program{
static void Main(){
string mid=", middle part,";
Func<string string> anonDel=delegate(string param){
param+=mid;
param+=" and this was added to the string.";
return param;
}
Console.WriteLine(anonDel("Start of string"));
}
}
}
//注:令我想起了js
(2014.12.18)