不使用反射,返回一个返回IEnumerable<T>的通用扩展方法

4
考虑以下代码片段:

考虑以下代码片段:

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的解决方案也可以。

3个回答

4

只有当你有一种将Match转换为Ingredient的方法时,才能这样做。由于没有通用的方法来完成这个过程,你可能需要给你的方法一些帮助。例如,你的方法可以使用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 });

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

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

2
尝试类似以下代码(使用 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 });

2

You could first cast it...

matches.Cast<Match>()

然后您可以使用LINQ来转换生成的IEnumerable<Match>,以任何您想要的方式进行操作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接