第八讲 泛型和委托,lambda
var 和objict
var只能定义局部变量
程序在编写的时候,没有指定类型名称,而是由编译器在编译的时候,指定一个特别的名称
由于这种类型我们是无法明确知道的,所以我们使用var定义
//var和object的区别
var aa = 123;
object bb="zzl";
bb = 123;
// aa = "aaa"; 可以看到aa="aaa" 报错了,
//因为var是推断类型,根据右边的数据推断左边的类型,所以 aa就是int类型,然后我们使用aa="aaa"肯定报错,
//但是object是任意类型所有bb = 123;不错报错
var zzl = new
{
name = "zzz",
age = 23,
type = "mode"
};
//上面我们编写的程序,没有指定这个类的名称,有编译器在编译的时候指定一个特别的名称,我们无法知道这个对象的类型,所以我们使用var
匿名方法和lambda表达式
匿名方法:如果委托只有一个委托对象,可以用匿名方法简化
匿名方法:没有方法名称,只有委托关键字,方法参数,方法体,所以是匿名方法
匿名方法单独定义意义并不大,但是如果我们使用lambda简化后就不一样了 ,
lambda就是匿名方法进一步封装,基本定义是:(参数列表)=>{方法体}
lambda的本质是匿名方法,匿名方法的本质是方法,所以lambda可以直接给委托赋值
Console.WriteLine("------------------------一般委托调用1.1--------------------------------------");
NLambdaTest myNl = new NLambdaTest();
myNl.Testdele1();
Console.WriteLine("------------------------使用匿名方法调用1.2--------------------------------------");
myNl.calDele1(20, 50);
Console.WriteLine("------------------------使用lambda调用1.3--------------------------------------");
myNl.callam1(30, 60);
Console.WriteLine("------------------------使用lambda的简化调用1.4--------------------------------------");
myNl.callam2(40,40);
Console.WriteLine("------------------------使用lambda有返回值的1.5--------------------------------------");
int y = myNl.mydel2(30);
Console.WriteLine(y);
Console.WriteLine("------------------------委托作为参数传递(传递lambda)1.6--------------------------------------");
//
myNl.MyShow((a, b, c) => {return (a + c) * b / (b - c); });
//下面是我们使用匿名方法穿的
myNl.MyShow(delegate(int a,int b,int c){return (a + c) * b / (b - c); });
//为什么可以传递, lambda是匿名方法,而匿名方法也是方法的一种,只要是方法,符合委托类型的都可以委托,所以可以传递
Console.WriteLine("------------------------泛型委托作1.7--------------------------------------");
int u= myNl.mydel4(30, 34);
Console.WriteLine("泛型委托的数据:" + u);
List<Course> courseList = new List<Course>
{
new Course { CourseId=1001, CourseName=".NET全栈课程VIP-1", CourseTeacher="常老师"},
new Course { CourseId=1002, CourseName=".NET全栈课程VIP-2", CourseTeacher="常老师"},
new Course { CourseId=1003, CourseName=".NET全栈课程VIP-3", CourseTeacher="常老师"},
new Course { CourseId=1004, CourseName=".NET全栈课程VIP-4", CourseTeacher="常老师"},
new Course { CourseId=1005, CourseName=".NET全栈课程VIP-5", CourseTeacher="常老师"}
};
//list的很多操作都是lambda比如我们的where
var lists = courseList.Where(c => c.CourseId > 1003);
foreach(var item in lists)
{
Console.WriteLine("系统实现的where:"+item.CourseId);
}
//通过了我们上面的讲解这个应该很好理解了
var listss = courseList.MyWhere(c => c.CourseId > 1003);
foreach (var item in lists)
{
Console.WriteLine("我们自己实现的where:" + item.CourseId);
}
//如果还不太明了我们可以吧上面的方法分解一下;定义一个匿名方法
Func<Course, bool> myFu = (c) => { return c.CourseId > 1003; };
var listsss = courseList.MyWhere(myFu);
foreach (var item in listsss)
{
Console.WriteLine("利用系统的你们方法分解:" + item.CourseId);
}
Console.Read();
namespace ConsoleApplication12
{
//[1]一般的委托
public delegate void dele1(int a,int b);
//[2]创建有返回值的委托
public delegate int dele2(int a);
//三个参数
public delegate int dele3(int a,int b,int c);
///泛型委托和一般的委托一样,就是参数类型不确定,我们这里就声明一下就可以
public delegate T dele4<T,T1>(T a,T1 b);
/// <summary>
/// 匿名方法和lambda,(lambda进化史)
/// </summary>
public class NLambdaTest
{
public void Add(int a,int b)
{
Console.WriteLine("一般委托输出:" + (a + b));
}
public void Testdele1()
{
dele1 mydele = Add;
mydele(10,40);
}
//使用匿名方法:简化委托的使用
//匿名方法:没有方法名称,只有委托关键字,方法参数和方法体
public dele1 calDele1 = delegate(int a, int b)
{
Console.WriteLine("使用匿名方法调用" + (a + b));
};
//当然了,匿名方法单独定义的话,没有太大的意义,但是如我我们使用lambda表示的话就不一样了
//=>我们读者 goes to
public dele1 callam1 = (int a, int b) =>
{
Console.WriteLine("使用lambda调用" + (a + b));
};
//使用lambda在一次简化
public dele1 callam2 = (a, b) =>
{
Console.WriteLine("使用lambda的简化调用调用" + (a + b));
};
//创建委托变量
public dele2 mydel2 = (int a) => { return a * a; };
public dele2 mydel3 = a => a * a;
//总结1:Lambda表达式参数类型可以是“明确类型”,也可以是根据上下文自动推断的类型
//总结2:Lambda表达式与匿名方法比较
//相同点:Lambda表达式本身就是匿名方法
//不同点1:Lambda表达式参数允许不明确,而匿名方法参数类型必须明确
//不同点2:Lambda表达式的方法体,允许单一或多条语句组成,而匿名方法不允许单一表达式。
//为什么可以传递, lambda是匿名方法,而匿名方法也是方法的一种,只要是方法,符合委托类型的都可以委托,所以可以传递
public void MyShow(dele3 de3)
{
int a = 10;
int b = 20;
int c = 30;
int y = de3(a, b, c);
Console.WriteLine("委托作为参数传递的lambda:" + y);
}
/// <summary>
/// 基于泛型委托的lambda
/// </summary>
public dele4<int, int> mydel4 = (a, b) =>
{
return a * b;
};
//【4.2】Action泛型委托,系统个我们提供了其实是两个,还有一个有返回值的Func
public Action<int, int, int> myAction = (a1, a2, a3) =>
{
int result = (a1 + a2) * a3;
Console.WriteLine(result);
};
//参数是从1到16个
//Action<int, int> myAction2 = (a1, a2) =>
//{
// int result = (a1 + a2) * a2;
// Console.WriteLine(result);
//};
//【4.4】Func泛型委托,最后一个表示返回值
public Func<int, int, string> myFunc = (a1, a2) =>
{
int result = a1 + a2;
return "Func委托调用返回结果:" + result;
};
//后面扩展方法中Func有重要的意义,Action在多线程中也非常重
}
}
namespace ConsoleApplication12
{
/// <summary>
/// 给对象扩展方法,必须是静态类,而且必须是静态方法,而且扩展的方法和使用的地方必须是在同一个命名空间,实现扩展的方法的作用域和访问级别是通过命名空间控制的
/// </summary>
public static class AddAction
{
/// <summary>
/// 针对int类型的扩展的无参数的方法
/// </summary>
/// <param name="num"></param>
/// <returns></returns>
public static int Square(this int num)
{
return num * num;
}
/// <summary>
/// 如果我们扩展的方法和系统方法重名了,那调用的是系统方法
/// </summary>
/// <param name="num"></param>
/// <returns></returns>
public static string ToString(this int num)
{
return "这个是字符串的表示结果(乘方):" + num * num;
}
/// <summary>
/// 通过我们理解上面的东西,我们可以自己扩展各种lambda的功能
/// </summary>
/// <param name="thisMy"></param>
/// <param name="mydele"></param>
/// <returns></returns>
public static IEnumerable<T> MyWhere<T>(this IEnumerable<T> thisMy, Func<T, bool> mydele)
{
List<T> mylist = new List<T>();
foreach(var item in thisMy)
{
if(mydele(item))
{
mylist.Add(item);
}
}
return mylist;
}
}
}