2010-04-16 65 views
4

考虑以下代码片段:通用扩展方法返回的IEnumerable <T>不使用反射

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基础的解决方案就足够了为好。

回答

4

仅当您有某种方法将匹配转换为成分时。由于没有通用的方法来执行此操作,因此您可能需要为您的方法提供一些帮助。例如,你的方法可能需要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 }); 

您也可以跳过创建自己的方法,只使用选择,与演员操作员处理MatchCollection的弱类型:

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

选项#2工作。谢谢 :) – roosteronacid 2010-04-16 08:35:57

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

你可以先投它...

matches.Cast<Match>() 

...然后转换结果IEnumerable<Match>但是你想要使用LINQ。