public class MyStringArray : IEnumerable
{
public IEnumerator GetEnumerator()
{
return (IEnumerator)new MyStringArrayEnumerator(this);
}
public MyStringArray(params string[] Strings)
{
strings = new string[10];
foreach(string s in Strings)
{
strings[
}
}
public void Add(string addedstr)
{
strings[
}
public string this[int strind]
{
get
{
return strings[strind];
}
set
{
strings[strind] = value;
}
}
public string[] strings;
public int
}
public class MyStringArrayEnumerator:IEnumerator
{
public MyStringArrayEnumerator(MyStringArray strarr)
{
this.strarr = strarr;
index = -1;
}
public bool MoveNext()
{
index++;
if(index>=strarr.strings.Length)
return false;
else
return true;
}
public void Reset()
{
index = -1;
}
public object Current
{
get
{
return(strarr[index]);
}
}
MyStringArray strarr;
int index;
}
class Class1
{
[STAThread]
static void
{
MyStringArray strarr = new MyStringArray("This","is","a","test.");
strarr.Add("You");
strarr.Add("are");
strarr.Add("Welcome");
strarr[2] = "another";
foreach(string s in strarr)
{
Console.WriteLine("{0}",s);
}
}
}
当断点跟踪到foreach的时候再往下跟踪,就不太明白了。首先程序读取strarr对象的时候进入了MyStringArray. GetEnumerator方法,然后获取到一个MyStringArrayEnumerator对象,然后,光标又到了foreach关键字上,接着进入了MyStringArrayEnumerator. MoveNext方法中,从这个方法跳出后,跟踪点有移到了string s in上,然后又跟踪到了MyStringArrayEnumerator. Current属性中,然后又回到string s in上…能得莫名其妙的。
当时,我说了一句者可能是IEnumerable接口的内部机制(我这个概念错误应该是很严重的,接口中不可能调用这些方法)。那是为什么跟踪的结果会这样。我试图改造循环显示的部分,用for循环,但是发现strarr对象没有类似Count或Length的属性。
查看MSDN上对foreach使用的解释:
foreach (type identifier in expression) statement
其中:
type
identifier 的类型。
identifier
表示集合元素的迭代变量。如果迭代变量为值类型,则无法修改的只读变量也是有效的。
expression
对象集合或数组表达式。集合元素的类型必须可以转换为 identifier 类型。请不要使用计算为 null 的表达式。
而应计算为实现 IEnumerable 的类型或声明 GetEnumerator 方法的类型。在后一种情况中,GetEnumerator 应该要么返回实现 IEnumerator 的类型,要么声明 IEnumerator 中定义的所有方法。
statement
要执行的嵌入语句。
实际上,应该是foreach调用GetEnumerator方法,这个方法要返回一个IEnumerator对象。foreach应该是利用这个IEnumerator对象中方法实现的简单的便利。后来,试验了一下MyStringArray类不继承IEnumerable接口,但是实现了GetEnumerator方法,结果是一样的