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);
}
4

3 回答 3

4

当你调用第一个重载时,它会立即调用第二个重载。这不会执行其主体中的任何代码,这些代码将被移动到实现迭代器块的嵌套类中。当GetEnumerator()和 thenMoveNext()在返回时第一次被调用IEnumerable<TTo>那么你的第二个重载中的代码将开始执行。

我有一篇关于迭代器块实现的相当长的文章,您可能会觉得很有趣。

于 2009-02-09T14:46:19.913 回答
2

是的,因为yield return只是在编译时生成一个 IEnumerator 类。 yield return只是编译器的魔法。

于 2009-02-09T14:42:01.250 回答
2

顺便说一句……大多数类型转换器仅适用于字符串。这里另一个有趣的选项可能是针对类型定义的静态转换运算符 - 我有一些在MiscUtil中执行此操作的 .NET 3.5 代码- 请参阅此处Convert提到的方法。

回复您的评论:

我使用此方法的方式是将 EF 对象转换为 WCF 的 DataContract 对象。所以 List(Hotels).ConvertTo(SerializableHotels, Hotels)()

听起来你应该使用序列化,或者如果属性名称有直接关系,可能类似于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);
}

除此之外,您可能最好谈论 aConversion<,>而不是 a TypeConverter

于 2009-02-09T14:51:37.247 回答