委托是可以指向方法的类型,调用委托变量时执行的就是变量指向的方法
用法
delegate 返回类型 方法名(参数);
举例:
internal class Program
{
static void Main(string[] args)
{
/* string list = "12321312";
var items = list.Where(c => char.IsLetter(c));*/
int i = 5;
Console.WriteLine(i);
Console.WriteLine("-----------------");
D1 d1 = c1;
d1();
d1 = c2;
d1();
}
static void c1()
{
Console.WriteLine("这是c1方法");
}
static void c2()
{
Console.WriteLine("这是c2方法");
}
delegate void D1();
}
.NET中定义了泛型委托Action(无返回值)和Func(有返回值),所以一般不用自定义委托类型。
用法:
Func=> Func<参数1类型,参数2类型,返回值类型> f = 方法
Action=> Action<参数1类型,参数2类型> a= 方法
举例:
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine("-----------------");
Funcf=Add;
Funcf2=f33;
Action f6 =f8;
}
static int Add(int i,int j) {
return i1+i2
}
static string f33(int i,int j)
{
return "xxx"
}
static void f1()
{
Console.WriteLine("这是c2方法");
}
delegate void D1();
}
}
委托可以指定匿名方法
用法:
Func f1=delegate (int i ,int b){
return $"{i}+{b}}"
}
string s =f1(1,2)
//第二种用法
Func f2=(int i ,int b)=>{return $"{i}+{b}}"}
Console.Write(f2(1,3));
int[]nums =new int []{3,99,88,77,7,8,9,66,15,7};
IEnumerableitems=nums.Where(i=>i>10);
//using System.Linq
上述问题如何通过方法实现
internal class Program
{
static void Main(string[] args)
{
int[] nums = new int[] { 3, 99, 88, 77, 7, 8, 9, 66, 15, 7 };
var list = nums.Where(p => p > 10);
foreach (var item in list)
{
Console.WriteLine(item);
}
Console.WriteLine("-------where1---------");
var items2 = myWhere1(nums, a => a > 10);
foreach (var item in items2)
{
Console.WriteLine(item);
}
Console.WriteLine("------where2----------");
var items3 = MyWhere(nums, a => a > 10);
foreach (var item in items3)
{
Console.WriteLine(item);
}
}
static IEnumerable myWhere1(IEnumerable nums, Func f)
{
List list = new List();
foreach (var item in nums)
{
if (f(item))
{
list.Add(item);
}
}
return list;
}
static IEnumerable MyWhere(IEnumerablenums, Func f)
{
foreach (var item in nums)
{
if (f(item) == true)
{
yield return item;
}
}
}
}
var可以让编译器的“类型推断”来简化类型的声明,在LINQ中常用。
C#中的var和JavaScript的var不一样,仍然是强类型的。
C#中的弱类型是dynamic
LINQ中提供了大量类似Where的拓展方法,简化数据处理。大部分都在System.Linq命名空间中。
record Employee
{
public long Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public bool Gender { get; set; }
public int Salary { get; set; }
}
list.Add(new Employee { Id = 1, Name = "jerry", Age = 28, Gender = true, Salary = 5000 });
list.Add(new Employee { Id = 2, Name = "jim", Age = 33, Gender = true, Salary = 3000 });
list.Add(new Employee { Id = 3, Name = "lily", Age = 35, Gender = false, Salary = 9000 });
list.Add(new Employee { Id = 4, Name = "lucy", Age = 16, Gender = false, Salary = 2000 });
list.Add(new Employee { Id = 5, Name = "kimi", Age = 25, Gender = true, Salary = 1000 });
list.Add(new Employee { Id = 6, Name = "nancy", Age = 35, Gender = false, Salary = 8000 });
list.Add(new Employee { Id = 7, Name = "zack", Age = 35, Gender = true, Salary = 8500 });
list.Add(new Employee { Id = 8, Name = "jack", Age = 33, Gender = true, Salary = 8000 });
通过where进行筛选
IEnumerable list1 = list.Where(e => e.Salary > 2500 && e.Age < 35);
foreach (Employee e in list1)
{
Console.WriteLine(e);
}
可以计算满足条件的所有数量
int count1 = list.Count(e => e.Salary > 5000 || e.Age < 30);
int count2 = list.Where(e => e.Salary > 5000 || e.Age < 30).Count();
只要有一条满足的情况下则为true
bool b1 = list.Any(e => e.Salary > 8000);
bool b2 = list.Where(e => e.Salary > 8000).Any();
Employee e1 = list.Single(e => e.Id == 6);
Console.WriteLine(e1);
Employee? e2 = list.SingleOrDefault(e => e.Id == 9);
if (e2 == null)
{
Console.WriteLine("没有Id==9的数据");
}
else
{
Console.WriteLine(e2);
}
Employee e3 = list.First(e => e.Age > 30);
Console.WriteLine(e3);
Employee? e4 = list.FirstOrDefault(e => e.Age > 30);
if (e4 == null)
{
Console.WriteLine("没有大于30岁的数据");
}
else
{
Console.WriteLine(e2);
}
Employee e5 = list.First(e => e.Salary > 9999);
Order()对数据正序排序;
OrderByDescending()倒序排序;
list.OrderBy(e=>e.Age); 通过年龄排序
对于简单类型排序,也许不用lambda表达式。
特殊案例 按照最后一个字符排序;用Guid或者随机数进行排序。
Console.WriteLine("------按照年龄正序排列------");
var orderedItems1 = list.OrderBy(e => e.Age);
foreach (var item in orderedItems1)
{
Console.WriteLine(item);
}
Console.WriteLine("------按照工资倒序排列------");
var orderedItems2 = list.OrderByDescending(e => e.Salary);
foreach (var item in orderedItems2)
{
Console.WriteLine(item);
}
-----------------------------
//通过GUid排序
var item2=list.orderBydescending(e=>Guid.NewGuid());
//随机数排序
var item3 =list.OrderByDescending(e=>rand.Next())
-------------------------
//多条件排序
//通过年龄进行排序,年龄相同的通过工资从打道夏排序
var items=list.OrderByDescending(e=>e.Age).thenBy(e=>e.Salary);
var orderedItems1 =list.Skip(2).Take(3);
// Skip(),Take()也可以单独使用
Max() 取最大
Min() 取最小
Average() 平均值
Sum() 求和
Count() 求数量
LINQ中所有的拓展方法都是针对IEnumerable接口的,而几乎所有能返回集合的都返回IEnumerable,所以是可以吧几乎所有的方法“链式使用”的
//查询出年龄大于30的,工资最小的
list.Where(e=>e.Age>30).Min(e=>e.Salary)
IEnumerable> items = list.GroupBy(e => e.Age);
foreach (IGrouping item in items)
{
int age = item.Key;
int count = item.Count();
int maxSalary = item.Max(e => e.Salary);
double avgSalary = item.Average(e => e.Salary);
Console.WriteLine($"年龄{item.Key},人数{count},最高工资{maxSalary},平均工资{avgSalary}");
}
IEnumerable ages=list.Select(e=>e.Age);
IEnumerable names=list.Select(e=>e.Gender?"男":"女");
var dogs =list.Select(p=>new Dog{NickName=e.Name,Age=e.Age});
var list2= list.Select(e => new { Xingming = e.Name, Xingbie = e.Gender ? "男" : "女" });
foreach(var i in list2)
{
Console.WriteLine("姓名:" + i.Xingming + ",性别:" + i.Xingbie);
}
//通过年龄进行分组 求出这个年龄下的最高薪资和最低薪资以及这个年龄总共有多少人
var items1 =list.GroupBy(p=>p.Age).Select(p=> new {Nianling=p.Key,MaxS=p.Max(e=>e.Salary),MinS=p.Min(e=>e.Salary),Renshu=p.Count()});
foreach(var e in items1)
{
Console.WriteLine(e.Nianling+","+e.MaxS+","+e.MinS+","+e.Renshu);
}
有一些地方需要数组类型或者List类型的变量,我们可以用ToArray()和ToList()分别把IEnumerable< T > 转换为数组类型和List< T >类型。
IEnumerable items2 = list.Where(p => p.Salary>6000);
List list3 = items2.ToList();
Employee[] array2 = items2.ToArray();
上述使用 Where,OrderBy ,Select等拓展该方法进行数据查询的语法叫做“LINQ方法语法”
,还有一种“查询语法”的写法
比如
var items3 = from e in list
where e.Salary > 3000
orderby e.Age
select new
{
e.Name,
e.Age,
Gender = e.Gender ? "男":"女"
};
string txt= "61,90,100,99,18,22,38,66,80,93,55,50,89";
//先通过,进行切割
var items = txt.Split(",");
//需要将其转换成 int 类型然后进行求平均值
double avg = items.Select(e=>Convert.ToInt32(e)).Average();
Console.WriteLine(avg);
//思路:首先先要去除空格和逗号,在将其转换成小写,再将其分组 获取次数 在进行排序
string s = "Hellow WORD,hhhhh,LaAALSDSADSs";
var items2 = s.Where(c => char.IsLetter(c)).Select(c => char.ToLower(c))
.GroupBy(c => c)
.Select(g => new { g.Key, Count = g.Count() })
.OrderByDescending(g => g.Count)
.Where(g=>g.Count>2);
foreach(var i in items2)
{
Console.WriteLine(i);
}