C#的委托、匿名函数、lamda表达式简单理解,lambda的list.MoveALL()的应用

时间:2021-08-19 19:08:04

1、单例模式

     只能创建一个对象,

2、委托

使用委托可以把一个方法作为参数传入到函数中:

namespace delegation2
{
class Program
{
static void Main(string[] args)
{
string[] names = { "Vivi","Weal","Bary","Cherry","Queen"};
// 完成3个功能:1、将名字都写成大写
//2、将名字都改为小写
//3、将名字前面加上序号
//按照平时逻辑,将写三个方法进行处理

Program pr = new Program(); // 在这里了需要注意,下面的三个方法我都没有加static,所以非静态类型的方法引用需要创建对象,实例化来引用;

pr.StrToUpper(names); //如果方法加了static,直接函数名引用:StrToUpper(names);
foreach (var item in names)
{
Console.WriteLine(item);
}
Console.WriteLine("=========一条华丽丽的分割线==========");
pr.StrToLower(names);
foreach (var item in names)
{
Console.WriteLine(item);
}
Console.WriteLine("=========一条华丽丽的分割线==========");
pr.StrAddNum(names);
foreach (var item in names)
{
Console.WriteLine(item);
}
Console.ReadKey();
}
void StrToUpper(string [] names)
{
for (int i = 0; i < names.Length;i++ )
{
names[i]=names[i].ToUpper();
}
}
void StrToLower(string [] names)
{
for (int i = 0; i < names.Length;i++ )
{
names[i] = names[i].ToLower();
}
}
void StrAddNum(string [] names)
{
for (int i = 0; i < names.Length; i++)
{
names[i] = i.ToString ()+names[i];
}
}
}
}



委托函数

namespace delegation2
{
public delegate string StrTo(string names); // 声明一个委托类型,签名与方法相同

class Program
{
static void Main(string[] args)
{
string[] names = { "Vivi","Weal","Bary","Cherry","Queen"};

1) DelTest(names, StrToUpper);
================================================
2) //声明一个委托对象,在调用函数
StrTo str = StrToUpper;
str(names);
}

//构造一个使用委托类型的函数
public static void DelTest(string [] strnames,StrTo del)
{
for (int i = 0; i < strnames.Length;i++ )
{
strnames[i] = del(strnames[i]);
}
}
public static string StrToUpper(string name)
{
return name.ToUpper();
}
public static string StrToLower(string name)
{
return name.ToLower ();
}
}
}



匿名函数:没有名字的函数,只用一次;

格式:delegate(参数列表){方法体}

1、匿名函数的签名也要跟委托一样

namespace delegation2
{
public delegate string StrTo(string names); // 声明一个委托类型,前面与方法相同
class Program
{
static void Main(string[] args)
{
string[] names = { "Vivi","Weal","Bary","Cherry","Queen"};
DelTest(names,delegate(string name)
{
return name.ToLower();
});
// 这里引用了匿名函数(本质还是函数)
//当方法只执行一次时,可以考虑使用匿名函数

}

//构造一个使用委托类型的函数
public static void DelTest(string [] strnames,StrTo del)
{
for (int i = 0; i < strnames.Length;i++ )
{
strnames[i] = del(strnames[i]);
}
}
}
}


lamda表达式:本质是匿名函数

(函数的参数列表) goes  to  {方法体}: 

(参数列表)  =>   {方法体}

namespace delegation2
{
public delegate string StrTo(string names); // 声明一个委托类型,签名与方法相同

class Program
{
static void Main(string[] args)
{
string[] names = { "Vivi","Weal","Bary","Cherry","Queen"};

DelTest(names,delegate(string name)// 这个委托函数这里可以写成匿名函数,也可以写成lamda表达式
{
return name.ToLower();
});
// 这里引用了匿名函数(本质还是函数,没有名称)
////当方法只执行一次时,可以考虑使用匿名函数

//lamda表达式:相当于把匿名函数按照一定的格式重新写出来,换种方式写,更简单
StrTo str = (string name) => { return name.ToLower (); }; //(参数)=>(goes to){方法体}

str("A");
Console.WriteLine(str("A"));
DelTest(names,str);
}

//构造一个使用委托类型的函数
public static void DelTest(string [] strnames,StrTo del)
{
for (int i = 0; i < strnames.Length;i++ )
{
strnames[i] = del(strnames[i]);
}
}
}
}

泛型委托:

利用委托处理,把类型声明为object,强制转换

求不同数据类型的数组中的最大值(string:字符中最大长度)

namespace delegation2
{
public delegate int DelCompare(object o1,object o2); // 声明一个委托类型,签名与方法相同

class Program
{
static void Main(string[] args)
{
string[] names = { "Vivi","Weal","Bary","Cherry","Queen"};

===============================================================================
a: object obb=GetMax(names, CompareString);// 这个地方可以写成匿名函数的形式
===============================================================================
b: object obb = GetMax(names, delegate(object o1, object o2)
{
string s1 = (string)o1;
string s2 = (string)o2;
return s1.Length - s2.Length;
});
================================================================================
c:也可以写成lamda表达式的形式
object obb = GetMax(names,(object o1,object o2)=>
{
string s1 = (string)o1;
string s2 = (string)o2;
return s1.Length - s2.Length;
} );
Console.WriteLine(obb);
Console.ReadKey();
}

// 求不同类型的数组的最大值
public static object GetMax(object[] num,DelCompare del)
{
object max=num[0];
for(int i=0;i<num.Length ;i++)
{
if(del(max,num[i])<0) //这里声明了委托函数,用来判断不同类型的数据比较后的结果
{
max=num[i];
}
}
return max;
}

public static int CompareInt(object o1,object o2)
{
int n1 = (int)o1;
int n2 = (int)o2;
return n1 - n2;
}
public static int CompareString(object o1,object o2)
{
string s1 = (string)o1;
string s2 = (string)o2;
return s1.Length - s2.Length;
}
}
}


//用到object,一般会产生拆装箱


泛型委托:利用泛型委托处理,不用object,不会发生拆装箱

namespace delegation2
{
public delegate int DelCompare<T>(T o1,T o2); // 声明一个委托类型,签名与方法相同

class Program
{
static void Main(string[] args)
{
string[] names = { "Vivi","Weal","Bary","Cherry","Queen"};

=========================泛型比较字符串数组=========================================
string s = GetMax<string>(names, delegate(string s1,string s2)
{
return s1.Length - s2.Length;
});

==========================泛型比较int型数组=========================================
int max=GetMax(new int[] {1,2,3,4,3,2},CompareInt);

//GetMax<string>决定了要处理的字符的类型
//GetMax<int>();处理int类型的数组
Console.ReadKey();
}
// 求不同类型的数组的最大值
public static T GetMax<T>(T[] num,DelCompare<T> del)
{
T max=num[0];
for(int i=0;i<num.Length ;i++)
{
if(del(max,num[i])<0) //这里声明了委托函数,用来判断不同类型的数据比较后的结果
{
max=num[i];
}
}
return max;
}
public static int CompareInt(int n1,int n2)
{
return n1 - n2;
}
}
}



匿名函数与lamda表达式的表达形式:

    public delegate void DelAdd1();  
public delegate void DelAdd2(int n1);
public delegate int DelAdd3(int n1);

class Program
{
static void Main(string[] args)
{
//对于三种类型的委托函数,采用匿名函数和lamda表达式的形式
DelAdd1 de1 = delegate() { };
DelAdd1 de11 = () => { };

DelAdd2 de2 = delegate(int n) { };
DelAdd2 de22 = (int n) => { };

DelAdd3 de3 = delegate(int n) { return n;};
DelAdd3 de33=(int n)=>{return n;};
}
}


lamda表达式的应用:List.MoveAll()

            List<int >  lis=new List<int>{1,2,4,5,3,4,5,33,4,33,2};
lis.RemoveAll(n=>n>10); // 使用lamda表达式,移除符合条件的函数