【问题标题】:Is it possible to perform Linq to return a collection as a HashSet instead of a List?是否可以执行 Linq 以将集合作为 HashSet 而不是 List 返回?
【发布时间】:2011-07-22 16:19:55
【问题描述】:

我正在使用以下 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> 中?

【问题讨论】:

    标签: linq linq-to-xml hashset


    【解决方案1】:

    作为为 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
                                       }))
    

    【讨论】:

    • 我喜欢这两种方法,但我会将其标记为答案,因为它不依赖于我创建扩展方法。
    • @KallDrexx:这就是我提到它的原因。我个人喜欢扩展方法(并且在我的扩展方法库中有 on),但有时,像这样一次性添加它也很高兴。
    【解决方案2】:

    LINQ to Objects 中没有ToHashSet&lt;&gt; 扩展方法,但是很容易写一个:

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

    当您处理命名类型时,您当然可以显式调用构造函数,但扩展方法最终看起来更简洁。

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

    【讨论】:

    • IEnumerable 中有错字。不幸的是,由于 SO 政策,我无法更正它。
    猜你喜欢
    • 1970-01-01
    • 2011-01-28
    • 1970-01-01
    • 2011-02-10
    • 1970-01-01
    • 2015-03-05
    • 2013-04-23
    • 1970-01-01
    相关资源
    最近更新 更多