为什么一个代码片段可以编译,而另一个不能

本文关键字:编译 不能 另一个 片段 代码 一个 为什么 | 更新日期: 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();