为什么我可以使用(字符串)而不能使用“字符串”;作为字符串“;在Linq到XML查询中
本文关键字:字符串 Linq XML 查询 我可以 可以使 不能 为什么 | 更新日期: 2023-09-27 18:26:34
所以我第一次深入研究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
的地方,它会抛出一个null引用异常。。好吧,让我们再试一次。我听说你可以把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
};
哦。这次我得到了一个编译器错误。
无法通过引用转换、装箱转换、取消装箱转换、包装转换或空类型转换
好吧,这很奇怪。。让我们搜索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
强制转换为字符串会引发null引用异常。。。不是吗?我认为as string
在这种情况下正是!?
这是如何工作的?为什么我可以进行显式强制转换,但不能进行显式as
强制转换?
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
,并且您正在尝试获取整数,那么您将使用ArgumentNullException
而不是NullReferenceException
。如果null
是要强制转换为的类型(即可为null的类型或字符串)的可接受值,则返回null
,没有任何异常。这就是为什么使用这些显式强制转换运算符比访问Value属性安全得多。
obj as string-这是一次将对象转换为字符串的尝试,可能会失败,也可能不会失败(如果失败,结果为null),不会引发异常。(string)obj-这是obj到字符串类型的显式转换,您告诉编译器obj是一个字符串。如果obj不是字符串类型,则会得到一个强制转换异常。
请参阅此链接以了解更多信息-C#中铸造/转换方法之间的差异