繁体   English   中英

通用扩展方法返回IEnumerable <T>而不使用反射

[英]Generic extension method returning IEnumerable<T> without using reflection

考虑这段代码:

public static class MatchCollectionExtensions
{
    public static IEnumerable<T> AsEnumerable<T>(this MatchCollection mc)
    {
        return new T[mc.Count];
    }
}

而这堂课:

public class Ingredient
{
    public String Name { get; set; }
}

有没有办法神奇地将MatchCollection对象转换为Ingredient集合? 用例看起来像这样:

var matches = new Regex("([a-z])+,?").Matches("tomato,potato,carrot");

var ingredients = matches.AsEnumerable<Ingredient>();


更新

纯粹的基于LINQ的解决方案也足够了。

只有你有办法将匹配转换为成分。 由于没有通用的方法来执行此操作,您可能需要为您的方法提供一些帮助。 例如,您的方法可以使用Func<Match, Ingredient>来执行映射:

public static IEnumerable<T> AsEnumerable<T>(this MatchCollection mc, Func<Match, T> maker)
{
  foreach (Match m in mc)
    yield return maker(m);
}

然后你可以按如下方式调用它:

var ingredients = matches.AsEnumerable<Ingredient>(m => new Ingredient { Name = m.Value });

您也可以绕过创建自己的方法,只需使用Select,使用Cast运算符来处理MatchCollection的弱类型:

var ingredients = matches.Cast<Match>()
                         .Select(m => new Ingredient { Name = m.Value });

尝试这样的事情(使用System.Linq命名空间):

public class Ingredient
{
    public string Name { get; set; }
}

public static class MatchCollectionExtensions
{
    public static IEnumerable<T> AsEnumerable<T>(this MatchCollection mc, Func<Match, T> converter)
    {
        return (mc).Cast<Match>().Select(converter).ToList();
    }
}

并可以像这样使用:

    var matches = new Regex("([a-z])+,?").Matches("tomato,potato,carrot");

    var ingredients = matches.AsEnumerable<Ingredient>(match => new Ingredient { Name = match.Value });

你可以先施展它......

matches.Cast<Match>()

...然后转换生成的IEnumerable<Match>但是你想要使用LINQ。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM