.NET i takie tam

Keyword yield

leave a comment »

I know .NET 2.0 was introduced some time ago, so I should be familiar with most of its features. But form time to time it surprises me with something that I didn’t know about or I knew but I wasn’t realising how cool it really was. Recently I discovered contextual keyword – yield. Contextual keyword is again feature of .NET 2.0 and simply it means that certain word can be a name of variable and it become keyword only in certain cases. The yield word became keyword only when we put it before return. And what it does? Well it allow us to implement enumerable class in terms on another class. For example, we have classes:

public class Person
{
    private string _name;

    public string Name
    {
        get { return _name; }
        set { _name = value; }
    }

    public Person()
    {
    }

    public Person(string name)
    {
        _name = name;
    }
}

public class Persons
{
    private Person[] _persons = new Person[4];

    public Persons()
    {
        _persons[0] = new Person("Adam");
        _persons[1] = new Person("Marcin");
        _persons[2] = new Person("Tomasz");
        _persons[3] = new Person("Filip");
    }
}

And we want to do something like this:

static void Main(string[] args)
{
    foreach (Person p in new Persons())
    {
        Console.WriteLine(p.Name);
    }
}

To achieve that we have to implement GetEnumerator method in the Persons class. We could do this like that:

public IEnumerator GetEnumerator()
{
    return _persons.GetEnumerator();
}

But we would miss whole point of this example. So we will take longer route and create PersonEnumerator class:

public class PersonEnumerator: IEnumerator
{
    private int _position = -1;
    private Person[] _persons;

    public PersonEnumerator(Person[] persons)
    {
        _persons = persons;
    }

    public object Current
    {
        get {
            return _persons[_position];
        }
    }

    public bool MoveNext()
    {
        _position += 1;
        return (_position < _persons.Length);
    }

    public void Reset()
    {
        _position = -1;
    }
}

Right now implementation of GetEnumerator method in the Persons class could look like this:

public IEnumerator GetEnumerator()
{
     return new PersonEnumerator(_persons);
}

So it is one solution but why create whole special class if keyword yield can generate it for us in CLR? Just delete the PersonEnumerator we don’t need it anymore and change the Persons.GetEnumerator method to something like this:

public IEnumerator GetEnumerator()
{
    foreach (Person p in _persons)
    {
        yield return p;
    }
}

Neat isn’t it?

Written by sakowicz

Październik 23, 2007 @ 7:51 pm

Napisane w .NET

Skomentuj

Wprowadź swoje dane lub kliknij jedną z tych ikon, aby się zalogować:

Logo WordPress.com

Komentujesz korzystając z konta WordPress.com. Log Out / Zmień )

Zdjęcie z Twittera

Komentujesz korzystając z konta Twitter. Log Out / Zmień )

Facebook photo

Komentujesz korzystając z konta Facebook. Log Out / Zmień )

Google+ photo

Komentujesz korzystając z konta Google+. Log Out / Zmień )

Connecting to %s

%d bloggers like this: