<自己实现foreach的功能,其实也就是foreach的原理> 新建了一个控制台应用程序
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace foreach原理
{
public class Person:IEnumerable
{
//想要遍历这个数组就需要实现IEnumerable的接口,实现这个接口的目的就是让当前类型中增加一个名字为GetEnumerator()的方法(其实我们仅仅是需要我们当前类型中有GetEnumerator()这么么一个方法,与它实现不实现IEnumerable这个接口没有半毛钱关系,那我们直接在当前类里定义这么一个方法不就行了吗?为什么还要去实现这个IEnumerable接口?答案是:为了方便,大家都这么做,所以我们就这么做。)
private string[] Friends = new string[] { "张三", "李四", "王五", "赵六" };
/// <summary>
/// GetEnumerator()方法的作用就是获取一个枚举器,拿到了枚举器就可以实现遍历了。
/// </summary>
/// <returns></returns>
public IEnumerator GetEnumerator()
{
//那这个方法中我们该写什么代码呢??? 我观察这个方法,知道它需要返回一个IEnumerator类型,既然它需要返回一个IEnumerator类型,所以我们就要给它返回一个IEnumerator这个接口的一个子类对象。那我们现在也没有这个IEnumerator接口的子类对象,怎么办呢? 答案是:我们直接写一个吧!
return new MyPersonEnumerator(this.Friends); //new一个MyPersonEnumerator类对象,顺便传递了当前类的Friends数组 给新new出来的对象来初始化
}
}
/// <summary>
/// MyPersonEnumerator类实现了IEnumerator接口,它就变成了一个枚举器
/// </summary>
public class MyPersonEnumerator : IEnumerator
{
private string[] _friends;
public MyPersonEnumerator(string [] str) //你要枚举(遍历)什么数据,只要通过这个方法把要遍历的数据传过来,就可以了
{
_friends = str;
}
//定义个下标(一般情况下,下标都是一开始指向了第一条数据的前一条,而第一条数据的下标是0)
private int index = -1;
//那我们来实现以下IEnumerator这个接口。 这个接口下面有三个方法
/// <summary>
/// 当前对象
/// </summary>
public object Current
{
get
{
if(index>=0 && index<_friends.Length)
{
return _friends[index];
}
else
{
throw new IndexOutOfRangeException();
}
}
}
/// <summary>
/// 向后移动的一条数据
/// </summary>
/// <returns></returns>
public bool MoveNext()
{
//当用户调用MoveNext()方法的时候,就应该让下标自增一下
if (index < _friends.Length-1)
{
index++;
return true;
}
return false;
}
/// <summary>
/// 重置到一开始的位置
/// </summary>
public void Reset()
{
//当用户手动调用Reset()方法的时候就给下标重置为-1 (如果不重置,下次用户想在遍历数据的时候,此时的下标就不是从-1,所以就没有办法从第一条数据开始遍历了。)
index = -1;
}
}
class Program
{
static void Main(string[] args)
{
Person p = new Person();
IEnumerator ie = p.GetEnumerator();//得到一个枚举器
while (ie.MoveNext()) //只要往后移动成功
{
string s= ie.Current.ToString(); //获取当前对象,
Console.WriteLine(s); //打印出当前对象 :打印出:张三 李四 王五 赵六
}
ie.Reset(); //遍历完后,将枚举器下标还原到第一条数据的前面。这样的话下面的遍历又可以继续了。
while (ie.MoveNext())
{
string s = ie.Current.ToString();
Console.WriteLine(s);
}
Console.ReadKey();
}
}
}
<1>=============================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
namespace linq
{
class Student
{
public string Name { get; set; }
public string Language { get; set; }
public string Position { get; set; }
public Student()
{
}
}
class Program
{
//IEnumerator与IEnumerable与Ilist与list的区别:IEnumerator其实就是一个迭代器,而当一个类继承了IEnumerable接口的时候,就会实现IEnumerable接口里面的唯一一个抽象方法GetEnumerator(),只要实现这个方法,那么我们就可以使用这个迭代器了。即可以使用foreach
//IList接口是继承了IEnumerator接口,IList接口在IEnumerator接口上扩展了一些方法,所以IList方法功能更多,而list类又是继承了Ilist接口并实现了接口中的方法的,并在Ilist接口的基础上又扩展了一些方法。所以list类的功能更多。但是我们在使用这些IEnumerable,IList和list的时候最好是按照实际情况来用,节约资源。list功能太多,很多时候我们用不到它那么多的功能,如果不需要的话,会造成资源浪费,牺牲性能了。
//LINQ语法一 LINQ即语言集成查询,是.NET Framework 3.5中新增的功能。其功能类似于数据库中的SQL语句(实际上LINQ就是针对.NET Framework的SQL):提供标准的、易于学习的查询和更新数据模式。
//从from开始用过SQL的朋友都知道,最简单的SQL语句SELECT record FROM tableName:获取表中的所有记录,那么对应于LINQ,其语法如下:
//from record in tableName select record。
//明显的差异是将from语句放到了句首,此种语法方式只是为了适应Visual Studio中智能提示(试想如果将from子句放在后面,先输入select语句,此时select的对象类型尚不确定,智能提示无法做出相应提示)
//SQL语句是从数据库表中查询出记录,而LINQ适应的数据源更广,包括SQL Server数据库、XML文档、ADO.NET数据集以及所有支持IEnumerable及IEnumerable<T>接口的任意对象集合。
//LINQ只是一种语法,LINQ查询语句实际上和我们常用的foreach语句相似:中间语言(IL)中并没有对应的foreach语句,编译器最终会将foreach语句转换为一些列的语句块,例如:
static void Main(string[] args)
{
string[] str = { "Id", "Age", "Name" ,"Name2"};
foreach (string s in str)
{
Console.WriteLine(s);
}
//转换为↓↓↓
IEnumerator e = str.GetEnumerator(); //实现这个方法后,就可以使用foeach语句遍历这个e对象了
//其实IEnumerable接口是非常的简单,只包含一个抽象的方法GetEnumerator(),它返回一个可用于循环访问集合的IEnumerator对象
//GetEnumerator()方法是IEnumerable接口里的一个抽象方法,它返回一个可用于循环访问集合的IEnumerator对象;
//一个集合要支持Foreach语句,必须实现接口IEnumerable接口,即必须实现IEnumerable接口的GetEnumerator方法
//任何集合类对象都有一个GetEnumerator()方法,该方法可以返回一个实现了 IEnumerator接口的对象,这个返回的IEnumerator对象既不是集合类对象,也不是集合的元素类对象,它是一个独立的类对象。通过这个对象,可以遍历访问集合类对象中的每一个元素对象。
//在创建枚举数之后或在调用 Reset 方法后,枚举数放置在集合的第一个元素之前,首次调用 MoveNext 方法会将枚举数移到集合的第一个元素。如果 MoveNext 越过集合的末尾,则枚举数将放置在集合中最后一个元素的后面,而且 MoveNext 返回 false。 当枚举数位于此位置时,在调用 Reset 之前,对 MoveNext 的后续调用也返回 false。 注:Reset方法是将枚举数设置为其初始位置,该位置位于集合中第一个元素之前。
while (e.MoveNext())
{
Console.WriteLine(e.Current); //Current是获取集合中的当前元素。词条语句和上面的foreach语句效果一样
}
//===================================下面才是真正的Linq语句与where==============================================
//在.NET Framework 3.5中为IEnumerable<T>接口加入了大量的扩展方法,这些方法为LINQ提供了实现基础(就像IEnumerable中GetEnumerator方法为foreach提供实现基础一样)
//例如,IEnumerable中的Where扩展方法,它和LINQ中的where子句对应,用于筛选数据:
//-----------------------------使用Where方法------------------
IEnumerable<string> query = str.Where(s => s.StartsWith("N"));
foreach (string s in query)
{
Console.WriteLine(s);
}
//------------------------------使用query语句-------------------
IEnumerable<string> query1 = from ss in str
where ss.StartsWith("N")
select ss;
foreach (string i in query1)
{
Console.WriteLine(i);
}
//**********************************************************------示例1------**********************
Student stt = new Student() { Name = "钱掌柜", Language = "数学", Position = "七侠镇" };
//创建一个Student类型的数组,里面放置的是Student对象
Student[] stu=new Student[]
{
new Student{Name="张三",Language="c#",Position="Leader"},
new Student{Name="李四",Language="c#",Position="Coder"},
new Student{Name="王五",Language="java",Position="Coder"}
};
//-----------------------linq语句实现----------遍历stu数---------------------
var queryPs = from s in stu
//where条件筛选,指定条件,选出Language为c#的对象
where s.Language == "c#"
select new { Name = s.Name, Position = s.Position };
foreach (var ss in queryPs)
{
Console.WriteLine(String.Format("Name:{0}\t\tPosition:{1}", ss.Name, ss.Position));
}
//------------------------------------------用where条件实现---------------------
IEnumerable<Student> queryLL = stu.Where(s => s.Language.StartsWith("c#"));
foreach (var v in queryLL)
{
Console.WriteLine("Name:{0}\t\tPosition:{1}", v.Name, v.Position);
}
//**********************************************************------示例2------**********************
string[] strings = { "dfdf", "b", "c123", "d" };
var queryS = from s in strings
where s.StartsWith("c")
select s;
foreach (string s in queryS)
{
Console.WriteLine(s);
}
//var vv = typeof(Type).GetProperties();
//foreach (var vvv in vv)
//{
// Console.WriteLine(vvv.Name);
//}
var sss = new { age = 25,Name="tom" };
string name = sss.Name;
Console.WriteLine(name);
var type1 = sss.GetType();
Console.WriteLine(type1.Name);
Console.ReadKey();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace LinqToEntity
{
class Program
{
static void Main(string[] args)
{
//点击项目右键-添加->新建项->ADO.NET实体数据模型,然后..选择你需要的表,点击完成。这里我选择是数据库是sales表的名字是xs,默认生成了一个实体容器名称 salesEntities
salesEntities salesEn = new salesEntities();
//用拉姆的表达式来查询实体中的数据
// var temp = salesEn.xs;
var query = salesEn.xs.Where(s => s.总学分>50);
foreach (var v in query)
{
Console.WriteLine(v.姓名);
}
Console.WriteLine();
//用Linq来查询实体中的数据
var temp2 = from x in salesEn.xs
where x.总学分 > 50
select x;
foreach (var v in temp2)
{
Console.WriteLine(v.姓名+v.学号+" "+v.姓别);
}
Console.ReadKey();
}
}
}
<2>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace 拉姆达表达式
{
class Program
{
static void Main(string[] args)
{
//-------------------------------------------------------使用Where方法
List<int> list = new List<int> { 1, 7, 8, 15, 95, 2, 5, 32 };
Program p = new Program();
var mylist = list.Where(s => s > 15);//筛选出list中大于15的元素
foreach(var v in mylist) //遍历mylist
{
Console.WriteLine(v); //输出95,32
}
//------------------------------------------------------使用query语句
var query = from s in list
where s > 15
select s;
foreach (var v in query) //遍历query
{
Console.WriteLine(v); //输出95,32
}
Console.ReadKey();
}
}
}
因篇幅问题不能全部显示,请点此查看更多更全内容