Is it a best practice to refactor an Interface method -- extracting a code fragment of a Interface method to create a new wrapping method?
From MSDN, I got an example as follows:
IEnumerator IEnumerable.GetEnumerator()
{
return (IEnumerator) GetEnumerator();
}
public PeopleEnum GetEnumerator()
{
开发者_如何学Go return new PeopleEnum(_people);
}
Why did the author do like this? Is it a best practice?
--------EDIT---------
MSDN article link : http://msdn.microsoft.com/en-us/library/system.collections.ienumerable.aspx
Why didn't the author do as follows:
IEnumerator IEnumerable.GetEnumerator()
{
return new PeopleEnum(_people);
}
I tried, it still works.
======= SECOND EDIT ==========
using System;
using System.Collections;
namespace MyEnumerableEnumerator
{
class Person
{
public Person(string name, int age)
{
Name = name;
Age = age;
}
public string Name { get; set; }
public int Age { get; set; }
}
class PeopleEnumerator : IEnumerator
{
int Position { get; set; }
Person[] People { get; set; }
int Length { get; set; }
public PeopleEnumerator(Person[] people)
{
People = people;
Position = -1;
Length = people.Length;
}
public bool MoveNext()
{
Position++;
return Position < Length;
}
public void Reset()
{
Position = -1;
}
public object Current
{
get
{
try
{
return People[Position];
}
catch (IndexOutOfRangeException)
{
throw new InvalidOperationException();
}
}
}
}
class People : IEnumerable
{
Person[] Persons { get; set; }
public People(Person[] people)
{
Persons = new Person[people.Length];
for (int x = 0; x < people.Length; x++)
Persons[x] = people[x];
}
//public IEnumerator GetEnumerator()
//{
// return new PeopleEnumerator(Persons);
//}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
private IEnumerator GetEnumerator()
{
return new PeopleEnumerator(Persons);
}
}
class Program
{
static void Main(string[] args)
{
Person[] persons = { new Person("Mark", 1), new Person("Siva", 2) };
People people = new People(persons);
foreach (Person person in people)
{
Console.WriteLine("Name: {0}, Age: {1}", person.Name, person.Age);
}
}
}
}
They did as they did because they wanted a typed iterator for a non-generic collection.
Edit
foreach works since the compiler does some "magic"
Try this with your changed code:
var enumerator = peopleList.GetEnumerator();
while (enumerator.MoveNext())
Console.WriteLine(enumerator.Current.firstName); //compile error.
It will not compile, you have to cast the enumerator to PeopleEnum or change back the return type.
Edit 2
You can read about foreach's implicit type casting here:
http://www.dev102.com/2009/07/28/pay-attention-to-the-foreach-implicit-casting/
http://csharpindepth.com/ViewNote.aspx?NoteID=1
And in the specification: http://msdn.microsoft.com/en-us/library/bb308966.aspx
Scroll down to last section in 26.1
Instead you can simply alter the code To:
IEnumerator IEnumerable.GetEnumerator()
{
return new PeopleEnum(_people);
}
OR To:
public IEnumerator GetEnumerator()
{
return new PeopleEnum(_people);
}
Since, there the IEnumerable interface is being imherited, we cant omit the implementaion for GetEnumerator() method.
Thats actually explicit interface implementation
精彩评论