为什么一个代码片段可以编译,而另一个不能
本文关键字:编译 不能 另一个 片段 代码 一个 为什么 | 更新日期: 2023-09-27 18:16:19
第一个编译并运行。第二个方法失败了,因为方法调用返回一个ICollection
。
下面的代码可以正常工作
foreach (XmlSchema schema in schemaSet.Schemas(targetNamespace))
{
Id = schema.Id;
Version = schema.Version;
}
既然我只打算得到一个模式,为什么不继续这样做呢
XmlSchema schema = schemaSet.Schemas(targetNamespace);
Id = schema.Id;
Version = schema.Version;
必须有类似的东西,第二个将工作?
如何做到这一点?
由于Schemas()
返回ICollection
,您不能将其转换为单个XmlSchema
元素。要从集合中获取单个元素,您需要:
var schema = schemaSet.Schemas(targetNamespace).Cast<XmlSchema>().First();
Id = schema.Id;
Version = schema.Version;
(这使用LINQ的IEnumerable.Cast<TResult>
将非泛型集合转换为泛型集合,因此您可以获得正确类型XmlSchema
的结果,因此您可能必须为System.Linq
添加using指令。)
您可以使用LINQ使第二个工作更容易:
XmlSchema schema = schemaSet.Schemas(targetNamespace).Cast<XmlSchema>().Single();
Id = schema.Id;
Version = schema.Version;
如果你确实希望只有一个模式,我肯定会选择使用Single()
而不是First()
——这样,如果你的期望出错了,你会抛出一个异常,而不是使用任何模式从意外的大集合中首先出现。
Cast<>()
调用是必需的,因为Schemas()
只返回弱类型的ICollection
,而不是IEnumerable<XmlSchema>
的实现。
你可以这样做:
XmlSchema schema = schemaSet.Schemas(targetNamespace).Cast<XmlSchema>().Single();
Id = schema.Id;
Version = schema.Version;
如果.Schemas()
返回0项,.Single()
将抛出异常。
您也可以使用.SingleOrDefault()
来确保不超过1,但如果有0则返回null:
XmlSchema schema = schemaSet.Schemas(targetNamespace).Cast<XmlSchema>().SingleOrDefault();
if(schema != null)
{
Id = schema.Id;
Version = schema.Version;
}
这两段代码不相等。第一部分代码遍历集合,并将值设置为集合中的最后一项。
要获得相同的行为,你需要做一个FirstOrDefault()或SingleOrDefault()来保护。schemas方法不返回元素的地方。
XmlSchema schema = schemaSet.Schemas(targetNamespace).FirstOrDefault();
if (schema != null)
{
Id = schema.Id;
Version = schema.Version;
}
编辑:注意Jon Skeet的回答添加
as XmlSchema
schemaSet.Schemas(targetNamespace)
是一个IEnumerable,不能赋值给XmlSchema
。
尝试将其分配给IEnumerable<XmlSchema>
之后,您必须选择一个已定义的。参见其他答案
请不要通过选择任意XmlSchemas而忽略XmlSchemas。
忽略信息通常是错误的方式。应该有一种合格的方法来查找所需的XMLSchema。
我认为First()
不是。
错误如下:
XmlSchema schema = schemaSet.Schemas(targetNamespace);
您正在尝试返回单个模式对象中的模式列表。这行不通。
你可以做:
IList<XmlSchema> schema = schemaSet.Schemas(targetNamespace);
和循环。
或this返回基于索引的特定模式。
XmlSchema schema = (from s in set.Schemas().Cast<XmlSchema>().ToList()
select s).FirstOrDefault();