1.匿名类
匿名类编译之后会生成一个具体的泛型类,匿名类的属性是只读的。在临时数据传递时非常方便(linq查询)。匿名类中不能有方法。数据传输(json),数据查询(linq)
var Person = new { Name = "jack", Age = };
2.匿名方法
匿名方法编译后会生成一个方法和一个指向该方法的静态的委托对象。匿名方法一定是结合委托使用。一次性使用的方法。匿名方法可以省略参数。
delegate void Say(string s);
static void Main(string[] args)
{
//1.将匿名方法指向委托的对象,相当于jquery中的匿名方法
Say s = delegate(string ss){
Console.WriteLine(ss);
};
//2.第二种写法,在lambda表达式中比较常用,编译后也会生成这样的
//Say s = (string ss)=>{ Console.WriteLine(ss);};
s("dd");
Say s1 = delegate{ Console.WriteLine(""); };//省略参数
//3. 将匿名方法指向系统委托
Func<int, int> f = delegate(int c)
{
return ++c;
};
Console.WriteLine(f());
Console.Read();
}
3.扩展方法
扩展方法的本质是调用静态方法。当编译器遇见this时,要转成运行时能够认识的语法(特性:ExtensionAttribute)。优先调用实例方法。当你使用其他程序集中的扩展方法时要先将扩展方法所在的程序集导入,并在当前类中引用命名空间。扩展方法可以被继承。
public static class MethodExten
{
public static string CutStr(this string s, int length)
{
return null; }
}
string tag="www";
tag.CutStr();
MethodExten.CutStr(tag, );//本质
4.系统内置委托:
(1)Action<in T1,….,int T16>,最多可以传入16个参数,无返回值。可以用来遍历集合。
public delegate void Action<in T1, in T2>(T1 arg1, T2 arg2);
(2)Predicate<T> 返回bool。public delegate bool Predicate<in T>(T obj);可以用来当条件。
(3)Comparison<T> 返回int。public delegate int Comparison<in T>(T x, T y); //list.Sort
(4)Func<in T1,…,in T16,out TResult>,自定义参数类型。public delegate TResult Func<in T, out TResult>(T arg);
例题:
static class Program
{
delegate void Say(string s);
static void Main(string[] args)
{
List<int> list = new List<int>() { , , , }; //1.系统委托1 Action<T>
Action<int> a = delegate(int i) { Console.WriteLine(++i); };
//利用系统委托aciton遍历集合
//list.ForEach(new Action<int>(delegate(int i) { Console.WriteLine(i); }));//同下
list.ForEach(delegate(int i) { Console.WriteLine(i); });
a(); //2.系统委托2 Predicate<T> 返回bool
list = list.FindAll(delegate(int i) { return i > ; }); //3.系统委托3 Comparison<T> 返回int 传入两个参数
list.Sort(new Comparison<int>(delegate(int x, int y) { return x - y; })); //4.系统委托4 Func 自定义参数的委托,最后一个参数为返回值类型
List<Dog> dogList = new List<Dog>() { new Dog() { Name = "jack", Age = } };
var smallDogList= dogList.GetSelect<Dog, SmallDag>(
delegate(Dog d) { return new SmallDag() { Name = d.Name };
});
//*****系统select扩展方法---简化过程 dogList.Select(new Func<Dog, SmallDag>(delegate(Dog c) { return new SmallDag { Name = c.Name }; }));
//将已知的对象转换成匿名类----将大量使用--因为无法确认返回类型,所以必须用var
var dlist= dogList.Select(delegate(Dog c) { return new { Name = c.Name }; });
dogList.Select((Dog c) => { return new { Name = c.Name }; });//简写版(lambda)
dogList.Select((c) =>{ return new { Name = c.Name }; });//省略参数类型
dogList.Select(c => { return new { Name = c.Name }; });//一个参数省略小括号,多个参数不能省略
dogList.Select(c =>new { Name = c.Name });//方法体只有一句时,省略return和花括号,如果有多条语句则必须加return 和花括号。
Console.Read();
}
//select扩展方法本质说明
static List<U> GetSelect<T, U>(this List<T> l, Func<T, U> func)
{
List<U> list = new List<U>();
foreach (T item in l)
{
list.Add(func(item));
}
return list;
}
} class Dog
{
public string Name { get; set; }
public int Age { get; set; }
}
class SmallDag
{
public string Name { get; set; }
}
5.Lambda表达式
Lambda表达式:Lambda不使用delegate关键字,而使用 Lambda运算符 =>。Lambda的本质是匿名方法,匿名方法的本质是委托,委托的本质是类。
标准查询运算符(SQO):定义在System.Linq.Enumerable类中的50多个为IEnumerable<T>准备的扩展方法,这些方法用来对它操作的集合进行查询筛选.例如:where(),select(),orderby(),count(),join()等等。
例题:
//join 等值连接 ????左外连接呢,怎么写(linq解决)
var lists= listDog.Join(listToy, d => d.Id, t => t.DogId, (d, t) => new {DogId=d.Id,DogName=d.Name,DToyName=t.ToyName }).ToList();
lists.ForEach(c=>Console.WriteLine(c));
//linq的等值连接
var r = (from d in listDog
join t in listToy
on d.Id equals t.DogId
select new {
DogId = d.Id, DogName = d.Name, DToyName = t.ToyName
}).ToList();
//linq的左外连接
var r = (from d in listDog
join t in listToy
on d.Id equals t.DogId
into temp
from ts in temp.DefaultIfEmpty()
select new { DogId = d.Id, DogName = d.Name, DToyName = (ts==null?"不存在":ts.ToyName) }).ToList();
r.ForEach(c => Console.WriteLine(c)); //group 分组查询
IEnumerable<IGrouping<int,Dog>> groups= listDog.GroupBy(d=>d.Age);//获得多个组
foreach (var group in groups)
{
Console.WriteLine("按年龄分组:"+group.Key+"----此组共有:"+group.Count());
foreach (var item in group)//循环每组(有多个Dog)
{
Console.WriteLine(item.Name);
}
Console.WriteLine("--------------");
} //skip take 分页 每页两行
int pageSize = ;
int pageIndex=;
var pageList= listDog.OrderByDescending(d=>d.Id).Skip((pageIndex-)*pageSize).Take(pageSize); static List<Dog> GetDogList()
{
List<Dog> dog = new List<Dog> {
new Dog(){ Id=,Name="jack",Age=},
new Dog(){ Id=,Name="tom",Age=},
new Dog(){ Id=,Name="loly",Age=},
new Dog(){ Id=,Name="kimi",Age=},
new Dog(){ Id=,Name="lily",Age=},
new Dog(){ Id=,Name="saly",Age=},
};
return dog;
}
static List<DogToy> GetDogToyList()
{
List<DogToy> dog = new List<DogToy> {
new DogToy(){ DogId=, ToyName="dd"},
new DogToy(){ DogId=, ToyName="沙发"},
new DogToy(){ DogId=, ToyName="沙发"} };
return dog;
}
6. LINQ
Linq:编译后的IL又生成了标准查询运算符(lambda)。标准运算符中除了分页的方法都能转换成linq。
例题:
//连接 多表查询---下面为等值连接即内连接
var data = from p in ps
join a in ana on p.PID equals a.PID
select new {PID=p.PID,PName=p.Name,PAge=p.Age,PPhone=p.Phone,AID=a.AID,AName=a.Name };
foreach (var item in data)
{
Console.WriteLine(item.PID+"--"+item.PName+"--"+item.PAge+"--"+item.PPhone+"--"+item.AID+"--"+item.AName);
}
Console.WriteLine("----------------左连接------------------------");
//左连接的写法
var data1 = from p in ps
join a in ana on p.PID equals a.PID
into temp //临时表
from t in temp.DefaultIfEmpty()
select new { PID = p.PID, PName = p.Name, PAge = p.Age, PPhone = p.Phone, AID =( t!=null?t.AID:), AName = (t!=null?t.Name:"null")};
foreach (var item in data1)
{
Console.WriteLine(item.PID + "--" + item.PName + "--" + item.PAge + "--" + item.PPhone + "--" + item.AID+ "--" + item.AName);
}