C#中实现类型对foreach的支持

   在C#中,MS提供了foreach关键字,与for相比在遍历集合元素的性能上得到了极大的提高。

foreach语句的执行原理

 

foreach  (car s  in  cars)
{
    Console.WriteLine(
"car's value: {0}", s);
}


IEnumerator ienum 
=  (IEnumerator)lbt.GetEnumerator();
ienum.Reset();

while (ienum.MoveNext()) {
    Car
 s = (Car)ienum.Current;
    Console.WriteLine(
"car's value: {0}", s);
}

由上面可知,一个类型要想支持foreach则必须实现IEnumerable,IEnumerator两个接口。

 

//  Namespace: System.Collections, Library: BCL
public   interface  IEnumerable {
    IEnumerator GetEnumerator();
}

 
//  Namespace: System.Collections, Library: BCL
public   interface  IEnumerator {
    
bool MoveNext();
    
void Reset();
    
object Current get; }
}

那么我们现在可以让自己定义的类型来支持foreach:

 

using  System;
using  System.Collections;
namespace  ConsoleEnum
{
   
public class cars : IEnumerator,IEnumerable
   
{
      
private car[] carlist;
      
int position = -1;

      
//Create internal array in constructor.
      public cars()
      
{
         carlist
= new car[6]
      
{
         
new car("Ford",1992),
         
new car("Fiat",1988),
         
new car("Buick",1932),
         
new car("Ford",1932),
         
new car("Dodge",1999),
         
new car("Honda",1977)
      }
;
      }


      
//IEnumerator and IEnumerable require these methods.
      public IEnumerator GetEnumerator()
      
{
         
return (IEnumerator)this;
      }


      
//IEnumerator
      public bool MoveNext()
      
{
         position
++;
         
return (position < carlist.Length);
      }


      
//IEnumerable
      public void Reset()
      
{position = 0;}

      
//IEnumerable
      public object Current
      
{
         
get return carlist[position];}
      }

   }
      
}

一些改进

为了代码的健壮性,我们对上述代码进行如下修改:

  1. 将IEnumerator以嵌套类的形式实现,这样你可以定义多个不同的Enumerator。
  2. 对IEnumerator的Current方法进行异常处理。如果集合的内容改变,或者Reset方法被调用,那么当前的enumerator就失效了,并且抛出IndexOutOfRangeException异常。所以我们用try......catch来捕捉这个异常并且产生一个InvalidOperationException异常。

 

using  System;
using  System.Collections;
namespace  ConsoleEnum
{
  
public class cars : IEnumerable
  
{
    
private car[] carlist;

    
//Create internal array in constructor.
    public cars()
    
{
      carlist
= new car[6]
    
{
      
new car("Ford",1992),
      
new car("Fiat",1988),
      
new car("Buick",1932),
      
new car("Ford",1932),
      
new car("Dodge",1999),
      
new car("Honda",1977)
    }
;
    }


        
//private enumerator class
        private class  MyEnumerator:IEnumerator
        
{
          
public car[] carlist;
          
int position = -1;

        
//constructor
        public MyEnumerator(car[] list)
        
{
          carlist
=list;
        }

        
private IEnumerator getEnumerator()
        
{
          
return (IEnumerator)this;
        }

    
    
        
//IEnumerator
        public bool MoveNext()
        
{
          position
++;
          
return (position < carlist.Length);
        }


        
//IEnumerator
        public void Reset()
        
{position = -1;}

        
//IEnumerator
        public object Current
        
{
          
get 
          

            
try 
            
{
              
return carlist[position];
            }

      
            
catch (IndexOutOfRangeException)
            
{
              
throw new InvalidOperationException();
            }

          }

        }

      }
  //end nested class
    public IEnumerator GetEnumerator()
    
{
      
return new MyEnumerator(carlist);
    }

  }

}
参考:MSDN

你可能感兴趣的:(.Net,c#,interface,object,constructor,library,class)