tags:

views:

219

answers:

3

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);
}
+2  A: 

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

Nick Berardi
+3  A: 

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
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
I have no firm opinion about type converters - but I know Marc knows a lot more about it than I do.
Jon Skeet
Actually, Jon - that sounds like a job for your property-mapper in MiscUtil (can't remember the name).
Marc Gravell
PropertyCopy.CopyFrom
Marc Gravell
+2  A: 

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
Thanks I'll take a look.
bendewey
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
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
Entirely up to you how you play it...
Marc Gravell
Gave it to Jon, but seriously thanks
bendewey