自定义类型使用foreach循环
来源:互联网 发布:微信打印软件 编辑:程序博客网 时间:2024/05/22 05:05
示例代码:
List<string> names = new List<string>();foreach(string name in names){ Console.WriteLine(name);}
以上foreach语句代码中,names类型是List。c sharp允许用户自定义自己的类型以便使用foreach语句。假设有类型People定义如下,
using System;public class People{ private Person[] persons; public People(Person[] persons) { this.persons = new Person[persons.Length]; for(int i = 0; i < persons.Length; i++) { this.persons[i] = persons[i]; } }}
其中,Person类的定义如下:
using System;public class Person{ private string name; private int age; public Person(string name, int age) { this.name = name; this.age = age; } public override string ToString() { return this.name + " " + this.age; }}
我们期待的使用foreach的效果如下:
// persons' type is Peopleforeach(Person person in persons){ Console.WriteLine(person);}
foreach语句的原理是从实现IEnumerable接口的类中调用GetEnumerator()方法,获得一个实现了IEnumerator的类,这个类中有Current, MoveNext等foreach语句必要的调用方法。这里,我们把实现了IEnumerable和IEnumerator的类看作使用foreach语句的工具类,即People和PersonEnum看作工具,实际数据Person看作被操作类型,如下:
更改People类实现IEnumerable接口。
public class People : IEnumerable{ private Person[] persons; public People(Person[] persons) { this.persons = new Person[persons.Length]; for(int i = 0; i < persons.Length; i++) { this.persons[i] = persons[i]; } } // implement the interface method explicitly IEnumerator IEnumerable.GetEnumerator() { return new PersonEnum(this.persons); }}
PersonEnum是实现了IEnumerator接口的由IEnumerable返回的类。实现PersonEnum类如下:
public class PersonEnum : IEnumerator{ private Person[] persons; private int position = -1; public PersonEnum(Person[] persons) { this.persons = persons; } public bool MoveNext() { position++; return position < this.persons.Length; } // return type is object object IEnumerator.Current { get { return Current; } } public void Reset() { position = -1; } public Person Current { get { try { return this.persons[position]; } catch(IndexOutOfRangeException) { return null; } } }}
查看使用效果:
using Systempublic sealed class Program{ static void Main(string[] args) { Person[] persons = new Person[3]; persons[0] = new Person("Owen", 22); persons[1] = new Person("Vincent", 21); persons[2] = new Person("Ricy", 20); People people = new People(persons); foreach (Person person in people) Console.WriteLine(person); }}
使用IEnumerable和IEnumerator,由于没有确定被操作的类型,使得操作对象为object,如Current属性的返回值,
object IEnumerator.Current
这使得类型不安全,为了确定类型,建议使用泛型化的IEnumerable和IEnumerator。
注意,实现接口IEnumerable和IEnumerator与实现接口IEnumerable和IEnumerator的类MyEnumberable是否需要泛型化,可以作出如下讨论。
public class MyEnumerable : IEnumerable
这种情况,使得MyEnumerable类正如上述实例中的People类,操作的只能是一种确定的类型(Person)。如果需要扩展被操作的类型,工具类People和PersonEnum操作其他类型,可以做如下泛型化:
public class People : IEnumerable
public class PersonEnum : IEnumerator
代码如下:
using System;using System.Collections;public class People<T> : IEnumerable{ // type to be operate could be any type private T[] persons; public People(T[] persons) { this.persons = new T[persons.Length]; for (int i = 0; i < persons.Length; i++) { this.persons[i] = persons[i]; } } IEnumerator IEnumerable.GetEnumerator() { return new PersonEnum<T>(this.persons); }}
更改PersonEnum:
using System;using System.Collections;public class PersonEnum<T> : IEnumerator{ private T[] persons; private int position = -1; public PersonEnum(T[] persons) { this.persons = persons; } public bool MoveNext() { position++; return position < this.persons.Length; } object IEnumerator.Current { get { return Current; } } public void Reset() { position = -1; } public T Current { get { try { return this.persons[position]; } catch (IndexOutOfRangeException) { return default(T); } } }}
注意泛型化之后,Current的catch块中返回default(T),值类型返回0,引用类型返回null。
检查效果:
using System;public sealed class Program{ static void Main(string[] args) { Person[] persons = new Person[3]; persons[0] = new Person("Owen", 22); persons[1] = new Person("Vincent", 21); persons[2] = new Person("Ricy", 20); People people = new People(persons); foreach (Person person in people) Console.WriteLine(person); string[] namelist = new string[3]; namelist[0] = "Owen"; namelist[1] = "Vincent"; namelist[2] = "Ricy"; People<string> names = new People<string>(namelist); foreach (string name in names) Console.WriteLine(name); }}
运行结果:
若MyEnumerable类实现IEnumerable,其自身不做泛型化,
public People : IEnumerable
这样的类型定义直接导致报错,
the type or namespace name ‘T’ could not be found
所以,People必须泛型化。
public People : IEnumerable
- 自定义类型使用foreach循环
- 自定义标签------forEach循环
- ForEach循环的使用
- 自定义标签的开发及使用自定义标签实现迭代foreach循环
- 自定义标签的开发及使用自定义标签实现迭代foreach循环
- forEach 当 for循环使用
- 对于foreach循环的使用
- Foreach循环语句的使用
- 集合类型的foreach循环浅析
- java 自定义类如何实现foreach循环
- C# 自定义类型实现foreach 迭代
- 【Java】Java中foreach循环的使用
- 使用foreach循环要注意的
- Java - for 和 foreach循环使用
- 初学java--foreach循环语句的使用
- 使用foreach循环输出数组中的元素
- Smarty使用foreach语句循环输出数组
- foreach循环
- vimcaps插件补充
- ISE约束控制
- 硬币问题
- 分布式服务框架--Dubbo
- 牵一发而动全身的CPU性能指标
- 自定义类型使用foreach循环
- 模板类实现二叉树前序、中序、后序遍历
- 获取html的当前级以及上一级的导航名称
- [JAVA]堆排
- Android学习第十二篇——Fragment基础学习
- 欢迎使用CSDN-markdown编辑器
- android oom分析步骤
- Android 点击两次返回键退出程序
- 斐波那契