foreach遍历原理

 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

内存地址一样啊啊啊

 

 

     

 

posted @ 2014-03-30 23:32  Bend  阅读(734)  评论(0编辑  收藏  举报