0

I have the following classes:

class Word { }
class Sentence: List<Word> { }
class TextSection: List<Sentence> { }
class TextBase: List<TextSection> { }

And I want to be able to work with TextBase as if it was a collection of Words, i.e. iterate over it with foreach, use Select and Aggregate methods.

There are some important additional fields and methods in all of those classes so replacing them with TextBase: List<Word> is not an option.

What is the best way to do that?

UPD: Implementing IEnumerable<Word> will solve part of my problem, but now when I call TextBase.Where() it will return IEnumerable<Word> It will ruin my breakdown of base into sections, sections into sentences etc. Can I avoid that?

0x60
  • 3,104
  • 1
  • 15
  • 18
  • 1
    Check this http://stackoverflow.com/questions/9455043/how-do-i-make-a-class-iterable – hgulyan Apr 20 '14 at 20:15
  • @user3554721 do you mean that you want to flatten `TextBase` to list of `Word`? – dkozl Apr 20 '14 at 20:19
  • @hgulyan Thank you. But see UPD. – 0x60 Apr 20 '14 at 20:42
  • @dkozl Not exactly. I want to work with it as if it was flattened. For instance, filter it with `Where` preserving my breakdown of base into sections, sections into sentences, sentences into words. – 0x60 Apr 20 '14 at 20:50

3 Answers3

1

If you have TextBase implementing both IEnumerable<TextSection> (via List) and IEnumerable<Word> it is going to be a pain to work with LINQ because you will have to specify types in every LINQ method like Where and Select. It's best to create a property like Words that you can use iterate the words.

Something like:

class TextBase : List<TextSection>
{
    public IEnumerable<Word> Words
    {
        get { return this.SelectMany(s => s.Words); }
    }
}

class TextSection : List<Sentence>
{
    public IEnumerable<Word> Words
    {
        get { return this.SelectMany(s => s); }
    }
}
Mike Zboray
  • 39,828
  • 3
  • 90
  • 122
0

You can implement IEnumerable in TextBase:

class TextBase: List<TextSection>, IEnumerable<Word>
{     
    IEnumerator<Word> IEnumerable<Word>.GetEnumerator()
    {
        return ((List<TextSection>)this).SelectMany(c => c.SelectMany(w => w)).GetEnumerator();
    }
}
Kirill Bestemyanov
  • 11,946
  • 2
  • 24
  • 38
-2

Why not add a property?

    public IEnumerable<Word> Words
    {
        get
        {
            // return all words somehow, maybe using yield
        }
    }
catbert
  • 1,017
  • 1
  • 9
  • 19