• Welcome to Valhalla Legends Archive.
 

Oooh, I just wrote my first C# iterator property! :D

Started by MyndFyre, July 13, 2006, 03:53 AM

Previous topic - Next topic

MyndFyre

I was trying to come up with an efficient way to iterate through the MPQ patch list backwards without loading them in reverse order in my code.  This is what I came up with:

public IEnumerable<MpqArchive> Patches
        {
            get
            {
                for (int i = m_patches.Length - 1; i >= 0; i--)
                {
                    yield return m_patches[i];
                }
            }
        }


I've been having difficulty coming up with the utility for this.  I have to say I'm pretty impressed.  First I thought of a custom collection class, then I thought about overriding the GetEnumerator property of List<MpqArchive>, but that didn't pan out (nonvirtual method).  Then I thought about that, jotted it down, first compile I got it right and I was amazed at how straightfoward it was.

:D
QuoteEvery generation of humans believed it had all the answers it needed, except for a few mysteries they assumed would be solved at any moment. And they all believed their ancestors were simplistic and deluded. What are the odds that you are the first generation of humans who will understand reality?

After 3 years, it's on the horizon.  The new JinxBot, and BN#, the managed Battle.net Client library.

Quote from: chyea on January 16, 2009, 05:05 PM
You've just located global warming.

topaz

RLY...?

MyndFyre

If you write a custom property for it.  List<T> for instance does not have any virtual methods, so I opted out of using that because I don't like to get the "Member xxx hides inherited member xxx" warning.  However, if you did something like:


public class SpecialList<T> : List<T>
{
    public IEnumerable<T> BackwardsList
    {
        get
        {
            for (int i = Count - 1; i >= 0; i--)
            {
                yield return this[i];
            }
        }
    }
}


Then, to use the code, instead of foreach'ing the object, you foreach the property:

foreach (T item in mySpecialList.BackwardsList)
{
    // do something with the list backwards....
}


It's just a more coherent way of doing things.  You could have done it in .NET 1.x too, but you needed to implement the IEnumerable interface.
QuoteEvery generation of humans believed it had all the answers it needed, except for a few mysteries they assumed would be solved at any moment. And they all believed their ancestors were simplistic and deluded. What are the odds that you are the first generation of humans who will understand reality?

After 3 years, it's on the horizon.  The new JinxBot, and BN#, the managed Battle.net Client library.

Quote from: chyea on January 16, 2009, 05:05 PM
You've just located global warming.

MyndFyre

I'm looking at the decompilation of it in .NET Reflector:


public IEnumerable<MpqArchive> Patches
{
      get
      {
            InterfaceData.<get_Patches>d__0 d__1 = new InterfaceData.<get_Patches>d__0(-2);
            d__1.<>4__this = this;
            return d__1;
      }
}


Then there's a hidden child subclass contained by InterfaceData (the class I added the Patches property to):

[CompilerGenerated]
private sealed class <get_Patches>d__0 : IEnumerable<MpqArchive>, IEnumerable, IEnumerator<MpqArchive>, IEnumerator, IDisposable
{
      // Methods
      [DebuggerHidden]
      public <get_Patches>d__0(int <>1__state);
      private bool MoveNext();
      [DebuggerHidden]
      IEnumerator<MpqArchive> IEnumerable<MpqArchive>.GetEnumerator();
      [DebuggerHidden]
      IEnumerator IEnumerable.GetEnumerator();
      [DebuggerHidden]
      void IEnumerator.Reset();
      void IDisposable.Dispose();

      // Properties
      MpqArchive IEnumerator<MpqArchive>.Current { [DebuggerHidden] get; }
      object IEnumerator.Current { [DebuggerHidden] get; }

      // Fields
      private int <>1__state;
      private MpqArchive <>2__current;
      public InterfaceData <>4__this;
      public int <i>5__1;
}

So that's how it works.  The compiler generates a new class that implements all of the interfaces needed for foreach. :o
QuoteEvery generation of humans believed it had all the answers it needed, except for a few mysteries they assumed would be solved at any moment. And they all believed their ancestors were simplistic and deluded. What are the odds that you are the first generation of humans who will understand reality?

After 3 years, it's on the horizon.  The new JinxBot, and BN#, the managed Battle.net Client library.

Quote from: chyea on January 16, 2009, 05:05 PM
You've just located global warming.