6

I don't have much experience with using the yield keyword. I have these IEnumerable<T> extensions for Type Conversion.

My question is does the first overloaded method have the same yield return effect that I'm getting from the second method?

public static IEnumerable<TTo> ConvertFrom<TTo, TFrom>(this IEnumerable<TFrom> toList)
{
    return ConvertFrom<TTo, TFrom>(toList, TypeDescriptor.GetConverter(typeof(TTo)));
}

public static IEnumerable<TTo> ConvertFrom<TTo, TFrom>(this IEnumerable<TFrom> toList, TypeConverter converter)
{
    foreach (var t in toList)
        yield return (TTo)converter.ConvertFrom(t);
}
bendewey
  • 39,709
  • 13
  • 100
  • 125

3 Answers3

4

When you call the first overload, it will immediately call the second overload. That won't execute any of the code in its body, which will have been moved into a nested class implementing the iterator block. When GetEnumerator() and then MoveNext() are first called on the returned IEnumerable<TTo>, then the code in your second overload will begin executing.

I have a fairly long article on the iterator block implementation, which you may find interesting.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Do you agree with @Marc Gravell? the way I'm using this method is to translate an EF object into a DataContract object for WCF. so List(Hotels).ConvertTo(SerializableHotels, Hotels)(); – bendewey Feb 09 '09 at 15:07
  • I have no firm opinion about type converters - but I know Marc knows a lot more about it than I do. – Jon Skeet Feb 09 '09 at 15:35
  • Actually, Jon - that sounds like a job for your property-mapper in MiscUtil (can't remember the name). – Marc Gravell Feb 09 '09 at 15:38
2

Yes, because yield return just generates an IEnumerator class on compile. yield return is just compiler magic.

Nick Berardi
  • 54,393
  • 15
  • 113
  • 135
2

As an aside... most type-converters only work to/from strings. Another interesting option here might be the static conversion operators defined against the type(s) - I have some .NET 3.5 code that does this in MiscUtil - see the Convert method mentioned here.

Re your comment:

the way I'm using this method is to translate an EF object into a DataContract object for WCF. so List(Hotels).ConvertTo(SerializableHotels, Hotels)()

It sounds like you should either be using serialization, or if the property names have a direct relationship, maybe something like PropertyCopy<To>.CopyFrom(from) - this is again from MiscUtil (but some of Jon's work this time) - i.e.

public static IEnumerable<TTo> ConvertFrom<TTo, TFrom>(
    this IEnumerable<TFrom> list, TypeConverter converter)
{
    return list.Select(item => PropertyCopy<TTo>.CopyFrom<TFrom>(item);
}

Other than that, you're probably better-off talking about a Conversion<,> rather than a TypeConverter.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • Marc, this is great. I'm not sure if I can use it due to some licensing issues. I'll have to check but thanks – bendewey Feb 09 '09 at 16:07
  • I'd like to give you the answer, because you answered my hidden un-asked question, and I thank you. Although, the others answered the exact question that I asked about the usage of yield. Thoughts? – bendewey Feb 09 '09 at 16:11