Why can I use (string), but not "as a string" in Linq to XML queries?

So, this is the first time I'm immersed in Linq in XML (I know that I'm behind), and so far it's pretty cool. However, I came across this very confusing behavior.

I am parsing the common .resx format. It has data tags that have value and optional comment . Here is the code I tried first:

  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 }; 

Of course, when I get the .value element of the comment element, but it throws an exception with an empty link. Well, try again. I heard that you can overlay an XElement on a string and it will magically work. Let's try to

  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 }; 

Ohhhh. This time I get a compiler error.

It is not possible to convert the type 'System.Xml.Linq.XElement' to 'string' through link conversion, box conversion, decompression conversion, packaging conversion, or null type conversion

Well, this is strange .. Let the search stackoverflow. And so, I find a snippet that offers this instead:

  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") }; 

Wow. It works!? But, casting null to a string throws a link reference exception ... right? I thought that as string was exactly for this situation !?

How does it work and why can I make an explicit cast, but not an explicit expression of as ?

+4
source share
2 answers
 str.Element("comment") as string 

This checks if the XElement string. But this is not the case - XElement not inferred from a string, therefore it is not a string. That is why you have a mistake.

 (string)str.Element("comment") 

This is an overloaded statement that gets the Value property inside:

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

It first checks to see if the operand is null and simply returns null if so. That is why you have no exception.


BTW is an interesting thing with these explicit casting operators - none of them will throw a NullReferenceException , because they check the element for null before accessing it. Property Value. Even if the element is null and you are trying to get an integer, then instead of a NullReferenceException you will get an ArgumentNullException . And if null is a valid value for the type you are producing onto (i.e. Types with a null value or strings), then null returned without any exception. Therefore, using these explicit casting operators is much safer than accessing the Value property.

+9
source

obj as string is an attempt to convert an object to a string that may or may not fail (if it fails, the result is zero), an exception will not be thrown. (string) obj is an explicit cast of obj to a string of type, you tell the compiler that obj is a string. If obj is not a string type, you will get a cast exception.

Refer to this link for further understanding. The difference between casting / converting methods in C #

0
source

Source: https://habr.com/ru/post/1495566/


All Articles