views:

149

answers:

1

Alright, hard to phrase an exact title for this question, but here goes... I have an abstract class called Block, that looks something like this:

public abstract class Block
{
   public bool Enabled{get; private set;}

   public virtual IEnumerable<KeyValuePair<string, string>> GetDefaultUsages()
   {
      yield return new KeyValuePair<string, string>("Enabled", "true");
   }
}

And say I have a subclass:

public class Form : Block
{
   public string Key{get; private set;}

   public override IEnumerable<KeyValuePair<string, string>> GetDefaultUsages()
   {
       yield return new KeyValuePair<string,string>("Key", string.Empty);

       // can't do: yield return base.GetDefaultUsages()
   }
}

The idea is that GetDefaultUsages() will always return an IEnumerable containing all the string,string pairs that were specififed through the entire inheritance chain. I was initially hoping that the yield keyword would support a statement like:

yield return (some IEnumerable<T> object);

But apparently that doesn't work. I realize that I could do:

foreach(KeyValuePair<string, string> kv in base.GetDefaultUsages())
{
   yield return kv;
}

But I was hoping for a slightly cleaner syntax (and avoiding creating all the unnecessary intermediate IEnumerators).

Anyone got any ideas of a good way to implement this???

+2  A: 

You have to do something like the foreach method because the base.GetDefaultUsages() return an IEnumerable. yield return deals with single items, not collections. Although it would be nice if yield return could return a collection of object.

2 weeks ago John Oxley asked a similar question.

Edit: It seems that Bart Jacobs, Eric Meyer, Frank Piessens and Wolfram Schulte already wrote a very interesting paper about something they call nested iterators, which is basically what you're asking for.

JohannesH
Isn't that exactly what I said in the question?
LorenVS
Yup, yield foreach isn't there yet. See http://blogs.msdn.com/wesdyer/archive/2007/03/23/all-about-iterators.aspx for some discussion
Nader Shirazie
Yeah and my answer is confirming your solution to the problem. A foreach enumerating the base collection is the solution thus far. Hopefully in the future C# will support returning collections with yield return.
JohannesH
Alrightey, thanks for the link to the John Oxley question anyways, some good material there
LorenVS