为什么我可以在Linq中使用(字符串)而不是“as string”来查询XML?

时间:2013-08-06 15:58:23

标签: c# xml linq linq-to-xml

所以我第一次潜入Linq to XML(我知道,我在时代的背后),到目前为止它非常酷。但是,我遇到了这种非常令人困惑的行为。

我正在解析常见的.resx格式。其中,您有data个标记,其中包含value和可选comment。这是我最初尝试的代码:

        var items = from str in doc.Root.Descendants("data")
            select new ResourceValue
            {
                Name = str.Attribute("name").Value,
                Value = str.Element("value").Value,
                Comment=str.Element("comment").Value
            };

当然,在我获得.value元素的comment的情况下,它会抛出一个空引用异常..好吧,让我们再试一次。我听说你可以将XElement转换成一个字符串,它会神奇地工作。我们试试吧

        var items = from str in doc.Root.Descendants("data")
            select new ResourceValue
            {
                Name = str.Attribute("name").Value,
                Value = str.Element("value").Value,
                Comment=str.Element("comment") as string
            };

哦。这次我得到编译器错误。

  

无法通过a将类型'System.Xml.Linq.XElement'转换为'string'   引用转换,装箱转换,拆箱转换,包装   转换或空类型转换

嗯,这很奇怪..让我们搜索stackoverflow。瞧,我发现了一个代表它的片段:

        var items = from str in doc.Root.Descendants("data")
            select new ResourceValue
            {
                Name = str.Attribute("name").Value,
                Value = str.Element("value").Value,
                Comment=(string)str.Element("comment")
            };

哇。这样可行!?但是,将null强制转换为字符串会抛出空引用异常......不是吗?对于这种情况,我认为as string 完全

这是如何工作的,为什么我可以进行显式演员,但不能进行明确的as演员表演?

2 个答案:

答案 0 :(得分:9)

str.Element("comment") as string

检查XElement是否为字符串。但事实并非如此 - XElement不是从字符串派生的,所以它不是字符串。这就是你有错误的原因。

(string)str.Element("comment")

这是一个重载的运算符,它在内部获得Value属性:

public static explicit operator string(XElement element)
{
    if (element == null)        
        return null;

    return element.Value;
}

首先检查操作数是否为null,如果是,则返回null。这就是为什么你没有例外。


BTW 这些显式的强制转换运算符很有趣 - 它们都不会抛出NullReferenceException,因为它们在访问它的Value属性之前检查了null为null。即使元素为null并且您尝试获取整数,也会使用ArgumentNullException而不是NullReferenceException。如果null是您要转换的类型的可接受值(即可空类型或字符串),则返回null,没有任何例外。这就是使用这些显式转换运算符比访问Value属性更安全的原因。

答案 1 :(得分:0)

obj as string - 这是尝试将对象转换为字符串,可能会或可能不会失败(如果失败,结果为null),则不会抛出任何异常。 (string)obj - 这是obj对类型字符串的显式转换,你告诉编译器obj是一个字符串。如果obj不是字符串类型,您将获得强制转换异常。

请参阅此链接以获取进一步的见解.- Difference between casting/conversion methods in C#