一:λ表达式(匿名函数)
匿名函数(Anonymous methods)
它提供了一种传递代码块作为委托参数的技术,它没有名称,只有主体
举例:
1:我们先声明一个委托
delegate void MyDelegate(string name, int age);
常规做法中:
2:我们通过委托来调用函数采纳如下做法:
与之对应的方法:
public void Student(string name , int age)
{
Debug.Log("My name is " + name + ", and my age is " + age + ".");
}
3:调用方法:
MyDelegate studentDelegate = new MyDelegate(Student);
studentDelegate("小王", 1);
//studentDelegate.Invoke("小王", 1);
4:现在我们使用匿名函数:
StudentDelegate studentDelegate1 = new StudentDelegate(delegate (string name, int age)
{
//注意:这个方法本来在外面。是无法访问到DateTime的实例,但是放在方法体里面就可以访问了
Debug.Log(dateTime);
Debug.Log("我是" + name + ",我年龄是" + age);
});
studentDelegate1("小李", 2);
相当于把方法的参数和方法体全部塞到Delegate实体内部,而只去掉了函数名
5:现在引入λ表达式
还是上述的代码段,我们将delegate也舍弃掉,而在括号内的参数后,使用=>(Goes to符号)指向函数体
StudentDelegate studentDelegate2 = new StudentDelegate( (string name, int age)=>
{
Debug.Log(dateTime);
Debug.Log("我是" + name + ",我年龄是" + age);
});
6:λ表达式的其他举例
Action action = () => Debug.Log("无返回值,无参数");
声明一个action委托,内部传输一函数,没返回值没参数,参数后跟Goes to指向符,指向函数体
Action<DateTime> action1 = time => { Debug.Log("没返回值,一个参数"); };
声明一个委托,没有返回值,只有一个参数,参数名叫time,其他如上
Func<DateTime > func = () => { return DateTime.Now; };
Func委托,有一个返回值,没参数,没返回值,所以括号是空括号,后面大括号内为返回值
上面的代码段也可以简化如下:
Func<DateTime> func1 = () => DateTime.Now;
将花括号省略
7:λ表达式在Unity中的使用(AddListener)
拿一个Button的添加监听事件的例子:
button.OnClick.AddListener
拿AddListener来说,它的官方解释是:
Add a listener to the new Event. Calls MyAction method when invoked
使用方法是:
UnityEvent m_Event = new UnityEvent();
m_Event.AddListener(MyAction);
也就是给一个事件添加一个反应
它的代码定义如下:
public void AddListener(UnityAction call);
所以内部参数是一个UnityAction,也就是一个委托类型,所以内部可以使用Lamda表达式
因此添加监听事件的简写形式如下:
button.OnClick.AddListener((没参数)=> Debug.Log("1"); );
二:Linq
LINQ(Language Integrated Query):语言集成查询
也就是用作查询的一些操作类库,它的核心就是对数据源的操作
它的作用有三个:
1、LINQ to Object 查询对象
2、LINQ to XML 查询XML文件
3、LINQ toADO.NET 查询数据库
下面的代码演示了从普通查询演变到LINQ查询,然后到自定义方法
public class LinqExample : MonoBehaviour
{
private void Start()
{
Show();
}
public void Show()
{
List<StudentList> studentlist = new List<StudentList>()
{
new StudentList
{
Id = 1,
Name = "张三",
Age = 1,
Address = "北京"
},
new StudentList
{
Id = 2,
Name = "李四",
Age = 2,
Address = "上海"
},
new StudentList
{
Id = 3,
Name = "王五",
Age = 3,
Address = "广州"
},
new StudentList
{
Id = 4,
Name = "雷六",
Age = 4,
Address = "深圳"
},
};//数据源
{
Debug.Log("--------------------普通查询--------------------");
foreach (var item in studentlist)
{
if(item.Age >= 2)
{
Debug.Log($"Id: { item.Id},姓名:{item.Name}");
}
}
Debug.Log("--------------------LINQ查询(扩展方法)--------------------");
//这里的Where是扩展方法,是小方块旁边有向下的箭头
var list = studentlist.MyWhere( s => s.Age >= 2);//返回值是bool类型
//完整的使用应该如下,花括号和return都可以省略
//studentlist.Where((s) => { return s.Age >= 2; });
//这里我们将遍历查询放到了前面,使用了LINQ的扩展方法where
foreach (var item in list)
{
Debug.Log($"Id: { item.Id},姓名:{item.Name}");
}
Debug.Log("--------------------LINQ查询(关键字)--------------------");
var list1 = from s in studentlist
where s.Age >= 2
select s;
//下面是一样的
}
}
}
/// <summary>
/// LinqWhere的源代码
/// 自行编写修改
/// </summary>
public static class ExtendMethod
{
public static List<StudentList> MyWhere(this List<StudentList> resource, Func<StudentList, bool> func)
{
var list2 = new List<StudentList>();
foreach (var item in resource)
{
if(func.Invoke(item))
{
list2.Add(item);
}
}
return list2;
}
}
public class StudentList
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public string Address { get; set; }
}
我们创建一个StudentList类来存储字段
然后在Show方法中实例化几个字段
常规查询:用foreach循环,然后加上if判断
LINQ的扩展方法查询:采用定义好的Where,加上λ表达式来查询
自定义的where见静态类ExtendMethod中的静态方法MyWhere
它的返回值是一个学生列表,参数是学生列表和Func委托,Func委托的参数是学生列表,返回值是bool类型
三:回调函数/模板方法
回调函数(CallBack Function):
如果一个函数的名字被当作参数,那么这个函数就是回调函数
它自身并没有什么特别,只是说它被当作参数使用了而已