繁体   English   中英

将非泛型集合转换为泛型集合的最佳方法是什么?

[英]What's the best way to convert non-generic collection to a generic collection?

我最近一直在教自己LINQ并将它应用于各种小谜题。 但是,我遇到的一个问题是LINQ-to-objects只适用于泛型集合。 是否有将非泛型集合转换为泛型集合的秘密技巧/最佳实践?

我当前的实现将非泛型集合复制到一个数组然后操作,但我想知道是否有更好的方法?

public static int maxSequence(string str)
{
    MatchCollection matches = Regex.Matches(str, "H+|T+");
    Match[] matchArr = new Match[matches.Count];
    matches.CopyTo(matchArr, 0);
    return matchArr
        .Select(match => match.Value.Length)
        .OrderByDescending(len => len)
        .First();
}

最简单的方法通常是Cast扩展方法:

IEnumerable<Match> strongMatches = matches.Cast<Match>();

请注意,这是延迟并流式传输其数据,因此您没有这样的完整“集合” - 但它是LINQ查询的完美数据源。

如果在查询表达式中为range变量指定类型,则会自动调用Cast

所以要完全转换你的查询:

public static int MaxSequence(string str)
{      
    return (from Match match in Regex.Matches(str, "H+|T+")
            select match.Value.Length into matchLength
            orderby matchLength descending
            select matchLength).First();
}

要么

public static int MaxSequence(string str)
{      
    MatchCollection matches = Regex.Matches(str, "H+|T+");
    return matches.Cast<Match>()
                  .Select(match => match.Value.Length)
                  .OrderByDescending(len => len)
                  .First();
}

实际上,您不需要调用OrderByDescending然后在这里调用First - 您只需要Max方法获得的Max 更好的是,它允许您指定从源元素类型到您尝试查找的值的投影,因此您可以在没有Select情况下执行:

public static int MaxSequence(string str)
{      
    MatchCollection matches = Regex.Matches(str, "H+|T+");
    return matches.Cast<Match>()
                  .Max(match => match.Value.Length);
}

如果您的集合中包含一些正确类型的元素,但某些元素可能不是,则可以使用OfType 当遇到“错误”类型的项时, Cast会抛出异常; OfType只是跳过它。

您可以在IEnumerable上使用CastOfType进行转换。 如果元素无法转换为声明的类型,则Cast将抛出非法转换,而OfType将跳过任何无法转换的元素。

matches.Cast<Match>();

暂无
暂无

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

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