是否可以执行Linq将集合作为HashSet而不是List返回?

时间:2011-07-22 16:19:55

标签: linq linq-to-xml hashset

我使用以下Linq-to-XML将一些XML结构加载到我的数据结构中。

    // Load all the definitions
var definitions = doc.Descendants(Constants.ScriptNode)
                     .Select(x => new TcScriptDefinition
                     {
                         Application = x.Attribute(Constants.AppAttribute).Value,
                         CaseName = x.Attribute(Constants.CaseAttribute).Value,
                         ActionType = x.Attribute(Constants.ActionAttribute).Value,
                         ScriptUnit = x.Attribute(Constants.UnitAttribute).Value,
                         ScriptMethod = x.Attribute(Constants.MethodAttribute).Value,
                         Parameters = x.Descendants(Constants.ParamNode)
                                       .Select(param => new TcScriptParameter
                                       {
                                           Code = param.Attribute(Constants.ParamCodeAttribute).Value,
                                           ParameterNumber = Convert.ToInt32(param.Attribute(Constants.ParamOrderAttribute).Value),
                                           DisplayString = param.Attribute(Constants.ParamDisplayAttribute).Value
                                       })
                                       .ToList()
                     })
                     .ToList();

问题是TcScriptDefinition.Parameters被定义为HashSet<TcScriptParameter>,因此ToList()无法编译,因为它返回List<T>

如何通过Linq将我的xml加载到HashSet<T>

2 个答案:

答案 0 :(得分:2)

LINQ to Objects中没有ToHashSet<>扩展方法,但编写一个很容易:

public static HashSet<T> ToHashSet<T>(this IEnumerable<T> source)
{
    // TODO: Argument validation here...
    return new HashSet<T>(source);
}

当你处理一个命名类型时,你当然可以明确地调用构造函数,但扩展方法看起来会更清晰。

我真的很想在框架中看到这一点 - 它是一个方便的小额外操作员。

答案 1 :(得分:2)

作为为ToHashSet创建扩展方法的替代方法,您还可以通过将相关部分更改为:

来动态构建HashSet<T>
Parameters = new HashSet<DecendantType>(x.Descendants(Constants.ParamNode)
                                   .Select(param => new TcScriptParameter
                                   {
                                       Code = param.Attribute(Constants.ParamCodeAttribute).Value,
                                       ParameterNumber = Convert.ToInt32(param.Attribute(Constants.ParamOrderAttribute).Value),
                                       DisplayString = param.Attribute(Constants.ParamDisplayAttribute).Value
                                   }))