Linq to xml,检索基于通用接口的列表

Rit*_*ita 1 c# xml linq

我有一个看起来像这样的XML文档

    <Elements>
     <Element>
      <DisplayName />
      <Type />
     </Element>
    </Elements>
Run Code Online (Sandbox Code Playgroud)

我有一个界面,

interface IElement
{
    string DisplayName {get;}
}
Run Code Online (Sandbox Code Playgroud)

以及一些派生类:

public class AElement: IElement

public class BElement: IElement
Run Code Online (Sandbox Code Playgroud)

我想要做的是编写最有效的查询来迭代XML并创建一个列表IElement,包含AElementBElement基于XML中的"Type"属性.

到目前为止我有这个:

IEnumerable<AElement> elements = 
    from xmlElement in XElement.Load(path).Elements("Element")
    where xmlElement.Element("type").Value == "AElement"
    select new AElement(xmlElement.Element("DisplayName").Value);

return elements.Cast<IElement>().ToList();
Run Code Online (Sandbox Code Playgroud)

但这只是为了AElement.有没有办法添加BElement相同的查询,并使其通用IEnumerable<IElement>?或者我是否必须为每个派生类型运行此查询一次?

dtb*_*dtb 6

您可以使用条件运算符:

IEnumerable<IElement> elements = 
    from xmlElement in XElement.Load(path).Elements("Element")
    let type = (string)xmlElement.Element("Type")
    let name = (string)xmlElement.Element("DisplayName")
    select type == "AElement"
         ? (IElement)new AElement(name)
         : (IElement)new BElement(name);
Run Code Online (Sandbox Code Playgroud)

或者,使用常规语法:

IEnumerable<IElement> elements =
    XElement.Load(path)
            .Elements("Element")
            .Select(xmlElement =>
{
    var type = (string)xmlElement.Element("Type");
    var name = (string)xmlElement.Element("DisplayName");

    switch (type)
    {
        case "AElement": return (IElement)new AElement(name);
        case "BElement": return (IElement)new BElement(name);
    }

    throw new Exception();
});
Run Code Online (Sandbox Code Playgroud)