【问题标题】:Why can I use (string) but not "as string" in Linq to XML queries?为什么我可以在 Linq to XML 查询中使用(字符串)而不是“作为字符串”?
【发布时间】:2013-08-06 15:58:22
【问题描述】:

所以我是第一次深入研究 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
            };

当然,虽然我得到comment 元素的.value,但它会引发空引用异常。好吧,让我们再试一次。我听说您可以将 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。瞧,我找到了一个提示这个的 sn-p:

        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 转换?

【问题讨论】:

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


    【解决方案1】:
    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。这就是为什么你没有例外。


    顺便说一句,这些显式转换运算符很有趣——它们都不会抛出 NullReferenceException,因为它们在访问元素的 Value 属性之前会检查元素是否为 null。即使元素是null 并且您正在尝试获取整数,那么您将拥有ArgumentNullException 而不是NullReferenceException。如果null 是您要转换为的类型的可接受值(即可为空的类型或字符串),则返回null,没有任何异常。这就是为什么使用这些显式转换运算符比访问 Value 属性更安全的原因。

    【讨论】:

    • 所以它没有隐式调用ToString()方法?
    • @TheSolution 不,如果元素不为空,它只会获取值
    【解决方案2】:

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

    请参阅此链接以获取更多信息。- Difference between casting/conversion methods in C#

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-23
      • 1970-01-01
      • 1970-01-01
      • 2020-09-25
      • 1970-01-01
      • 2017-03-17
      • 1970-01-01
      相关资源
      最近更新 更多