1.匿名方法的概念:一个方法没有具体的名称,而只有关键字delegate、方法参数、方法体、这种方法是匿名方法。

匿名方法的好处:将具体方法和委托直接关联在一起,如果我们基于委托只需要一个方法的时候,匿名方法肯定显得简单。

2.Lambda表达式:在C#3.0出现的。使用这种表达的可以更简练的编写代码块。

CalculatorDelegate cal3 = (int a, int b) => { return a + b; };
CalculatorDelegate cal4 = (a, b) => a - b;

【1】Lambad的参数类型可以是明确类型,也可以是推断类型。

【2】如果是推断类型,则参数类型可以由编译根据上下文自动推断出来

【3】运算符=>读作goes to,运算符左边输入参数,右边是表达式或者代码块。

【4】表达式有两种方式:

(input args)=>表达式
(input args)=>{ 语句1;语句2;语句3....}

【5】Lambda表达式和匿名方法的比较:

第一,Lambda本身就是匿名方法。

第二,Lambda表达式不允许指明参数类型,但是匿名方法必须要明确。

第三,Lambda表达式允许单一的表达式或者多条语句组成,而匿名方法不允许单一表达式。

3.自定义泛型委托

【1】为什么要用泛型委托?普通委托在数据类型上的限定是非常严格的,有时候我们的需求变化,可能适应不了,这时候考虑的就是泛型委托。

【2】泛型委托定义:本质上和泛型方法是非常类似的,泛型委托关联的时候可以是具体方法,匿名方法或者Lambda表达式。

【3】试想如果我们有五个参数、六个参数甚至更多的参数,按照目前的思路我们不得不定义很多种这种方法,很麻烦,这时候就要考虑系统泛型委托,所谓系统泛型委托,就是C#.NET为

我们定义好的泛型委托,可以直接拿来用。

4.自定义泛型委托:主要介绍两种,一种是有返回值的Func<T>和一种是没有返回值的Action<T>

Action<T>在多线程中用的非常多。

Func<T>在扩展方法中用的非常多。

结论:泛型委托作为方法参数,实际上传递的是一个具体方法或一个Lambda表达式! (多态一种表现)

a.自定义普通委托和Lambda表达式:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace AdVancedTest
{
public class LambdaDemo
{
public static void Test()
{
//委托关联独立的方法
CalCulatorDelegate MyCal1 = Add;
int result1 = MyCal1(10, 20);
Console.WriteLine("委托关联独立的方法来计算a+b=" + result1);
//委托关联匿名方法
CalCulatorDelegate MyCal2 = delegate (int a, int b) { return a + b; };
int result2 = MyCal2(30, 30);
Console.WriteLine("通过匿名方法来计算a+b" + result2);
//将匿名方法简化为Lambda表达式:goes to 参数列表(参数1,参数2....)=>{函数体}
CalCulatorDelegate MyCal3 = (int a, int b) =>
{
Console.WriteLine(100);
return a + b;
}; //进一步简化:假如方法中只有一行代码,可以省略{}
CalCulatorDelegate MyCal4 = (a, b) => a + b;
int result4 = MyCal4(40,50);
Console.WriteLine("简化Lambda表达式计算a+b="+result4);
SayHelloDelegate sayHello = (msg) => msg;
string result5= sayHello("Hello World");
Console.WriteLine("SayHello委托:"+result5); //Lambda表达式允许不指明参数类型,但是匿名方法必须要明确。
CalCulatorDelegate myCal5 = (a, b) => { return a + b; };
myCal5(10,12);
}
private static int Add(int a, int b)
{
return a + b;
}
}
//【1】声明委托
public delegate int CalCulatorDelegate(int a, int b);
public delegate string SayHelloDelegate(string msg);
}

输出结果为:

委托关联独立的方法来计算a+b=30
通过匿名方法来计算a+b60
简化Lambda表达式计算a+b=90
SayHello委托:Hello World

b.自定义泛型委托

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace AdVancedTest
{
public class GenericClass
{
public static void Test()
{
//范型委托关联具体方法,基于泛型委托,
MyGenericDelegate<int> myGenericDelegate1 = Add;
int result1 = myGenericDelegate1(10, 30);
Console.WriteLine("范型委托关联具体方法:" + result1); //泛型委托关联元祖方法
MyDelegate<string, int, int> myDelegate1 = Mymethod;
var result2= myDelegate1(); //使用元组的默认参数名
var result4 = Mymethod();
Console.WriteLine(result4.str+"\t"+result4.a+"\t"+result4.b);
Console.WriteLine(result2.Item1+result2.Item2+result2.Item3); //使用元组的自定义参数名
MyDelegate<string ,int ,int > myDelegate2 = Mymethod;
var result3 = myDelegate2();
Console.WriteLine(result3); //使用泛型委托:匿名方法
MyGenericDelegate<int> myGenericDelegate4 = delegate(int a,int b){ return a + b; };
MyGenericDelegate<double> myGenericDelegate5 = delegate (double a, double b) { return a + b; }; int result5=myGenericDelegate4(20,30);
Console.WriteLine(result5);
double result6 = myGenericDelegate5(20,30);
Console.WriteLine(result6); //使用泛型委托:Lambaa表达式
MyGenericDelegate<int> myGenericDelegate6 = (a, b) => a + b;
int result7= myGenericDelegate6(20, 30);
Console.WriteLine(result7); MyGenericDelegate<double> myGenericDelegate7 = (a, b) => a + b;
double result8= myGenericDelegate7(20, 30);
Console.WriteLine(result8);
}
private static int Add(int a, int b)
{
return a + b;
}
private static int Sub(int a, int b)
{
return a - b;
}
//元组C#7.0新操作:元組
private static (string str, int a, int b) Mymethod()
{
return ("C#.NET",4, 5);
} }
//定义泛型委托
public delegate T MyGenericDelegate<T>(T param1, T param2); public delegate (T1, T2, T3) MyDelegate<T1, T2, T3>(); }

输出结果

范型委托关联具体方法:40
C#.NET 4 5
C#.NET45
(C#.NET, 4, 5)
50
50
50
50

c.系统泛型委托

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace AdVancedTest
{
public class FuncDemo
{
/// <summary>
/// Func的基本使用: 在扩展方法中用的非常多,最后一个表示返回自类型
/// </summary>
/// <returns></returns>
public static int Test1()
{
Func<int, int, int> func1 = Add1;//输入,输入,输出
int result1 = func1(10, 20);
//直接使用Lambad表达式,第四个参数表示返回值为string类型
Func<int, int, int, string> fun3 = (a,b,c) => { return (a + b+c).ToString(); };
Func<int, int, int> func2 = (a, b) => a + b;
int result2 = func2(40,40);
string result3 = fun3(40,40,60);
Console.WriteLine("------------------------------------------------------------------------");
Console.WriteLine(result1);//30
Console.WriteLine(result2);//80
Console.WriteLine(result3);//140
return result1;
}
private static int Add1(int a,int b)
{
return a + b;
}
private static int Mul1(int a, int b)
{
return a * b;
}
/// <summary>
/// Func委托的重要使用
/// </summary>
/// <returns></returns>
///
//问题:给定一个数组 { 10, 9, 8, 7, 6, 5, 4, 3, 2 },从数组中指定位置抽取3个数,求和、求积
public int Test2()
{
//普通方法求和求积
int[] nums = new int[] { 10, 9, 8, 7, 6, 5, 4, 3, 2 };
Sum(nums,0,2); return Mul(nums,0,2);
} private int Sum(int[]nums,int From,int To)
{
int sum = 0;
for (int i=From;i<To;i++)
{
sum += nums[i];
}
return sum;
} private int Mul(int[] nums, int From, int To)
{
int mul = 1;
for (int i = From; i < To; i++)
{
mul *= nums[i];
}
return mul;
} //把Func委托做为参数传递实际传递的是一个具体的方法或者一个Lambda表达式:也是多态的一种表现
private static int Operation(Func<int,int,int> method,int[]nums,int from,int to)
{
int result = nums[from];
for (int i=from+1;i<to;i++)
{
//method(result,nums[i]):方法的返回值
result = method(result, nums[i]);
}
return result;
} public static void Test3 ()
{
int[] nums = new int [] { 10, 9, 8, 7, 6, 5, 4, 3, 2 };
int result1= Operation(Add1,nums,0,3);//计算加运算
int result2 = Operation(Mul1,nums,0,3);//计算乘法运算
Console.WriteLine("返回10+9+8="+result1);
Console.WriteLine("返回10*9*8="+result2);
}
}
}

d.Func<T>委托

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace OperationXml
{
public class A
{
bool bDeviceConnected = false;
public void test()
{
Variable.val = new VarRef<object>(() => bDeviceConnected, val => { bDeviceConnected = (bool)val; });
Console.WriteLine(bDeviceConnected);
Variable.val.Value = true;
Console.WriteLine(bDeviceConnected);
}
}
public class VarRef<T>
{
public Func<T> _get;
public Action<T> _set; /// <summary>
/// 传递一个系统泛型委托,实际传递的是一个泛型方法
/// @get:传递() => bDeviceConnected,获取bDeviceConnected
/// @set:设置bDeviceConnected的值
/// </summary>
public VarRef(Func<T> @get, Action<T> @set)
{
_get = @get;
_set = @set;
} /// <summary>
/// 属性,对bDeviceConnected进行读和写
/// </summary>
public T Value
{
get { return _get(); }
set { _set(value); }
} }
public class Variable
{
public static VarRef<object> val;
}
}

输出结果

False
True

匿名方法、Lambda表达和自定义泛型委托以及Func、Action系统泛型委托的更多相关文章

  1. C#委托总结-匿名方法&Lambda表达式

    1,匿名方法 匿名方法可以在声明委托变量时初始化表达式,语法如下 之前写过这么一段代码: delegate void MyDel(string value); class Program { void ...

  2. C# delegate event func action 匿名方法 lambda表达式

    delegate event action func 匿名方法 lambda表达式 delegate类似c++的函数指针,但是是类型安全的,可以指向多个函数, public delegate void ...

  3. 委托-异步调用-泛型委托-匿名方法-Lambda表达式-事件【转】

    1. 委托 From: http://www.cnblogs.com/daxnet/archive/2008/11/08/1687014.html 类是对象的抽象,而委托则可以看成是函数的抽象.一个委 ...

  4. 委托delegate 泛型委托action<> 返回值泛型委托Func<> 匿名方法 lambda表达式 的理解

    1.使用简单委托 namespace 简单委托 { class Program { //委托方法签名 delegate void MyBookDel(int a); //定义委托 static MyB ...

  5. C#多线程+委托+匿名方法+Lambda表达式

    线程 下面是百度写的: 定义英文:Thread每个正在系统上运行的程序都是一个进程.每个进程包含一到多个线程.进程也可能是整个程序或者是部分程序的动态执行.线程是一组指令的集合,或者是程序的特殊段,它 ...

  6. 18、(番外)匿名方法+lambda表达式

    概念了解: 1.什么是匿名委托(匿名方法的简单介绍.为什么要用匿名方法) 2.匿名方法的[拉姆达表达式]方法定义 3.匿名方法的调用(匿名方法的参数传递.使用过程中需要注意什么) 什么是匿名方法? 匿 ...

  7. c# 中的委托以及匿名方法lambda

    1.委托的定义internal delegate int MyAddFunDe(int a,int b)2.匿名方法1)MyAddFunDe fun = delegate(int a,int b){  ...

  8. 函数~匿名方法~lambda的逐渐过渡思想

    前提:基于委托实现 (1)使用函数名称 delegate void Printer(string s);//(1)申明委托 static void Main(string[] args) { //(3 ...

  9. 匿名函数 =匿名方法+ lambda 表达式

    匿名函数的定义和用途 匿名函数是一个"内联"语句或表达式,可在需要委托类型的任何地方使用. 可以使用匿名函数来初始化命名委托[无需取名字的委托],或传递命名委托(而不是命名委托类型 ...

随机推荐

  1. 面试突击79:Bean 作用域是啥?它有几种类型?

    Spring 框架作为一个管理 Bean 的 IoC 容器,那么 Bean 自然是 Spring 中的重要资源了,那 Bean 的作用域是什么意思?又有几种类型呢?接下来我们一起来看. PS:Java ...

  2. 第七十八篇:写一个按需展示的文本框和按钮(使用ref)

    好家伙, 我们又又又来了一个客户 用户说: 我想我的页面上有一个搜索框, 当我不需要他的时候,它就是一个按钮 当我想要搜索的时候,我就点一下它, 然后按钮消失,搜索框出现, 当我在浏览其他东西时,这个 ...

  3. Memlab,一款分析 JavaScript 堆并查找浏览器和 Node.js 中内存泄漏的开源框架

    Memlab 是一款 E2E 测试和分析框架,用于发现 JavaScript 内存泄漏和优化机会. Memlab 是 JavaScript 的内存测试框架.它支持定义一个测试场景(使用 Puppete ...

  4. Java 加载、编辑和保存WPS表格文件(.et/.ett)

    WPS表格文件是金山开发的专门用于处理表格数据的Office工具,属于WPS Office中WPS文字.WPS表格和WPS演示三大功能模块之一.通常以.et和.ett作为文件后缀.我们在通过后端来操作 ...

  5. Django 使用cmd 创建工程

    一.Django 安装 1 通过pip安装 Django 如果你是通过升级的方式安装Django,那么你需要先卸载旧的版本. Django 提供3种发行版本,推荐使用官方的稳定版本: 你的操作系统提供 ...

  6. Idea插件SequenceDiagram快速查看方法调用

    Idea打开setting->plugins安装插件SequenceDiagram 快速查看方法调用 在方法名上右键点击SequenceDiagram即可生成方法调用图 最上面一行为该方法涉及的 ...

  7. ProxySQL(3):Admin管理接口

    文章转载自:https://www.cnblogs.com/f-ck-need-u/p/9281199.html ProxySQL的Admin管理接口 当ProxySQL启动后,将监听两个端口: (1 ...

  8. 7.第六篇 二进制安装 kube-apiserver

    文章转载自:https://mp.weixin.qq.com/s?__biz=MzI1MDgwNzQ1MQ==&mid=2247483812&idx=1&sn=e6773e56 ...

  9. Elasticsearch: Ngrams, edge ngrams, and shingles

    Ngrams和edge ngrams是在Elasticsearch中标记文本的两种更独特的方式. Ngrams是一种将一个标记分成一个单词的每个部分的多个子字符的方法. ngram和edge ngra ...

  10. logstash中关于Jdbc输入配置选项详解

    Setting Input type Required clean_run boolean No columns_charset hash No connection_retry_attempts n ...