foreach遍历本质:实现了一个IEnumerable接口,
01.为什么数组和集合可以使用foreach遍历?
解析:因为数组和集合都实现了IEnumerable接口,该接口中只有一个方法,GetEnumerator()
02.数组是一种数据结构,它包含若干相同类型的变量。数组是使用类型声明的:type[] arrayName;
03.数组类型是从抽象基类型 Array 派生的引用类型。由于此类型实现了 IEnumerable ,因此可以对 C# 中的所有数组使用 foreach 迭代
我们可以自己写一下foreach遍历的原理:
首先我们先创建一个类:MyLIst 该类实现了IEnumerable接口,该接口中只有一个方法,GetEnumerator()
代码:
public class MyLIst:IEnumerable {
public void Add(object o) //数据类型可以自己顶
{ list.Add(o); }
ArrayList list = new ArrayList();
public IEnumerator GetEnumerator()
{
return new MyIEnumerator(list);
}
}
我们看到 GetEnumerator() 方法的返回值是 IEnumerator,return的是一个 MyIEnumerator(list)【注意,这里是调用他的构造函数】;
因此 我们创建一个类 MyIEnumerator,该类实现了IEnumerator接口,实现了改接口的3个方法
代码如下:
public class MyIEnumerator:IEnumerator
{
ArrayList li = new ArrayList();
int i = -1;//从第一条数据开始之前
public MyIEnumerator(ArrayList list)
{
this.li = list;
}
public object Current
{
get {return li[i]; }//读取下一条数据 }
public bool MoveNext()
{
bool flog = false;
if (i < li.Count - 1)//如果大于,怎返回true,得到下一条
{ i++; //迭代
flog = true;
}
return flog;
}
首先调用 MoveNext()方法,判断是否为true.如果成立则会读取下一条数据
测试类的代码:
class Program {
static void Main(string[] args) {
MyLIst li = new MyLIst();
li.Add(new Brid("大大"));
li.Add(new Plane(111));
foreach (IFly item in li)
{
item.Show();
}
Console.ReadKey();
}
}
结果输出的是
111
大大
我们还可以将obje 改成接口或者抽象类。
如果是接口时:
我们先创建一个接口:
public interface IFly { void Show(); }
然后分别让鸟和飞机实现该接口:
public class Brid: IFly
{ public string name { get; set; }
public Brid(string name) {
this.name = name; }
public void Show()
{ Console.WriteLine("我叫" + this.name+",今天的天气真好"); }
}
public class Plane:IFly
{ public string name { get; set; }
public Plane(string name)
{
this.name = name; }
public void Show()
{ Console.WriteLine("我叫"+this.name+ ",白云飘飘!"); }
}
则则是类
MyLIst li = new MyLIst();
li.Add(new Brid("大大"));
li.Add(new Plane("小小"));
foreach (IFly item in li)
{ item.Show();
}
Console.ReadKey();
}
}
结果输出
我叫大大,今天天气真好
我叫小小,白云飘飘!
下一个知识点:匿名类
1.匿名类是不能有名字的类,它们不能被引用,只能在创建时用New语句来声明它们。
2.匿名类型提供了一种方便的方法,可用来将一组只读属性封装到单个对象中,而无需首先显式定义一个类型。 类型名由编译器生成,并且不能在源代码级使用。 每个属性的类型由编译器推断。
3.可通过使用 new 运算符和对象初始值创建匿名类型
代码如下:
var stu = new
{
Name = "大大餐",
Age = 18
};
var st = new
{
Name = "sisi",
Age = 22
};
Console.Write(st.Name);
Console.WriteLine(st.Age);
Console.Write(stu.Name);
Console.WriteLine(stu.Age);
}
}
结果显示:
大大餐18
sisi22
如上所示,我们通过它,不需要创建类,那么麻烦,而且类中的属性卡哇伊根据我们自己而定。
最后一个知识点:
运算符重载
C# 允许用户定义的类型通过使用 operator 关键字定义静态成员函数来重载运算符。
我们直接看代码:
首先创建一个类:
public class Person {
public string Name { get; set; }
public int Age { get; set; }
public static int operator +(Person p1,Person p2) //注意static
{
return p1.Age + p2.Age;
} //重载==
public static bool operator ==(Person p1,Person p2) //如果进行两者之间的判断是,必须==和!=两个方法同时存在,不然会出错
{
return p1.Age == p2.Age;
}
public static bool operator !=(Person p1, Person p2)
{
return p1.Age != p2.Age;
}
public static int operator -(Person p1,Person p2)
{
return p1.Age - p2.Age;
}
测试类的代码:
class Program
{
static void Main(string[] args)
{
Person p1=new Person(){Name = "李小龙",Age =120};
Person p2=new Person(){Name = "甄子丹",Age = 20};
Console.WriteLine(p1+p2);
Console.WriteLine("对象p1的年龄减去p2的年龄");
Console.WriteLine(p1-p2);
if (p1==p2)
{
Console.WriteLine("内存地址一样啊啊啊");
}
Console.ReadKey();
}
}
输出的结果是:
40
0
内存地址一样啊啊啊