我有一个包含Unit
s:
<Unit Name="Length">
<Prefix Char="c"
IsSelected="false"
Factor="1"/>
<Prefix Char="d"
IsSelected="true"
Factor="104"/>
</Unit>
我想读一整个对象:
public static Dictionary<string, Unit> Units { get; set; }
public class Prefix
{
public Func<double, double> fnc = null;
public Prefix(string c, double f, bool i, bool ifix = false,string fn = null)
{
Char = c;
Factor = f;
IsFixed = ifix;
Unit.funcs.TryGetValue(fn, out fnc);
}
public bool IsSelected { get; set; }
public bool IsFixed { get; set; }
public double Factor { get; set; }
public string Char { get; set; }
}
public Unit() { }
public Unit(string n, List<Prefix> p)
{
_name = n;
Prefixes = p;
}
private List<Prefix> _prefixes;
public List<Prefix> Prefixes
{
get { return _prefixes; }
set { _prefixes = value; }
}
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
....
}
我现在有了这个:
Form.Units = (data.Descendants("Unit").Select(x => new Unit
(
x.Attribute("Name").Value,
(List<Prefix>) x.Descendants("Prefix").Select(p => new Prefix(
p.Attribute("Char").Value,
Convert.ToDouble(p.Attribute("Factor").Value),
p.Attribute("IsSelected").Value == "true",
p.Attribute("IsFixed").Value == "true",
p.Attribute("Func").Value)
)
)
)
).ToDictionary(x => x.Name, x => x);
并收到以下错误:
“无法转换类型的对象 'WhereSelectEnumerableIterator
2[System.Xml.Linq.XElement,DD.Prefix]' to type 'System.Collections.Generic.List
1 [DD.Prefix]'。“
显然(List<Prefix>)
那么查询必须是什么?如何在List&lt;&gt;?
中获取内容
答案 0 :(得分:1)
它不是一个列表,而是一个查询,所以你不能只将它转换为一个列表,但你可以调用它上面的ToList来枚举它并返回一个列表:
Form.Units = (data.Descendants("Unit").Select(x => new Unit
(
x.Attribute("Name").Value,
//(List<Prefix>) no casting needed
x.Descendants("Prefix").Select(p => new Prefix(
p.Attribute("Char").Value,
Convert.ToDouble(p.Attribute("Factor").Value),
p.Attribute("IsSelected").Value == "true",
p.Attribute("IsFixed").Value == "true",
p.Attribute("Func").Value)
).ToList() // you had an IEnumerable<Prefix> now this is a List<Prefix>
)
)
).ToDictionary(x => x.Name, x => x);
答案 1 :(得分:1)
为了扩展我的评论,这里有几件事。首先,您可以使用.ToList()
上的.Select
扩展程序将IEnumerable<T>
集合转换为List<T>
。
其次,如果查询中缺少任何属性或元素,您将获得空引用异常。您可以通过显式转换为string
(然后根据需要转换结果)安全地处理此问题。
更新后的查询如下所示:
Form.Units = (data.Descendants("Unit").Select(x => new Unit
((string)x.Attribute("Name"),
x.Descendants("Prefix").Select(p => new Prefix(
(string)p.Attribute("Char"),
Convert.ToDouble((string)p.Attribute("Factor")),
(string)p.Attribute("IsSelected") == "true",
(string)p.Attribute("IsFixed") == "true",
(string)p.Attribute("Func")).ToList()
)
)
)
).ToDictionary(x => x.Name, x => x);
请注意,在使用.Value
时,您不需要(string)
(因为.Value
已经string
)。
答案 2 :(得分:1)
我将以下列方式表达此代码..因为它避免了将参数构造函数限制为将这些类型约束为IEnuermable表达式。即避免在计划用于查询的类型上执行参数构造函数。
我将Decendents
中使用的类型设置为XmlElement
类型...但我确定这是不准确的......只需将其替换即可无论什么是正确的类型。
此外,此代码段并未考虑Unit.funcs.TryGetValue(fn, out fnc);
..并且它假定Func
类型上有属性名称Prefix
。您可以在分配/设置期间执行空检查。
data.Descendants("Unit")
.Select<XmlElement, Unit>(x => new Unit()
{
Name = x.Attribute("Name").Value,
Prefixes = x.Descendants("Prefix").Select<XmlElement, Prefix>(p => new Prefix()
{
Char = p.Attribute("Char").Value,
Factor = Convert.ToDouble(p.Attribute("Factor").Value),
IsSelectd = p.Attribute("IsSelected").Value == "true",
IsFixed = p.Attribute("IsFixed").Value == "true",
Func = p.Attribute("Func").Value
}).ToList()
})
.Select<Unit, KeyValuePair<string, Unit>>(unit => new KeyValuePair<string, Unit>()
{
Key = x.Name,
Value = x
})
.ToList()
.ForEach( kvp => {
Form.Units.Add(kvp.Key, kvp.Value);
});