2009-02-09 64 views
6

我对使用yield关键字没有多少经验。我有这些IEnumerable <T>类型转换的扩展。重载使用收益回报

我的问题是,第一个重载的方法有第二种方法得到的产量回报效果相同吗?

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); 
} 
+0

我会更新你的评论给乔恩... – 2009-02-09 15:38:16

+0

请设置你的评论作为这个thred的答案http://stackoverflow.com/questions/1947919/template-style-is-not-setting-有些偏好,我将其标记为已接受。 – FFire 2009-12-27 14:56:32

回答

4

当您调用第一个重载时,它会立即调用第二个重载。这将不会执行其正文中的任何代码,该代码已被移入实现迭代器块的嵌套类中。当GetEnumerator()然后MoveNext()首先在返回的IEnumerable<TTo>,然后上调用时,第二个重载中的代码将开始执行。

我有一个相当长的article on the iterator block implementation,你可能会觉得有趣。

+0

你同意@Marc Gravell吗?我使用这种方法的方式是将EF对象转换为WCF的DataContract对象。所以List(Hotels).ConvertTo(SerializableHotels,Hotels)(); – bendewey 2009-02-09 15:07:23

2

是的,因为产量回报只是产生在编译一个IEnumerator类。 yield return只是编译器的魔力。

2

另外......大多数类型转换器仅适用于字符串/字符串。这里另一个有趣的选项可能是根据类型定义的静态转换运算符 - 我有一些.NET 3.5代码在MiscUtil中执行此操作 - 请参阅Convert方法here

回复您的评论:

我使用这个方法的办法是 的EF对象转化为WCF一个 DataContract对象。所以 列表(酒店).ConvertTo(SerializableHotels, 酒店)()

这听起来像你应该要么是使用序列,或者如果属性名称有直接的关系,可能像PropertyCopy<To>.CopyFrom(from) - 这再次是从MiscUtil(但有些Jon的工作的这段时间) - 即

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

除此之外,你可能会更好过谈论Conversion<,>而非TypeConverter