I'm trying to write a generic method for fetching an XElement
value in a strongly-typed fashion. Here's what I have:
public static class XElementExtensions
{
public static XElement GetElement(this XElement xElement, string elementName)
{
// Calls xElement.Element(elementName) and returns that xElement (with some validation).
}
public static TElementType GetElementValue<TElementType>(this XElement xElement, string elementName)
{
XElement element = GetElement(xElement, elementName);
try
{
return (TElementType)((object) element.Value); // First attempt.
}
catch (InvalidCastException originalException)
{
string exceptionMessage = string.Format("Cannot cast element value '{0}' to type '{1}'.", element.Value,
typeof(TElementType).Name);
throw new InvalidCastException(exceptionMessage, originalException);
}
}
}
As you can see on the First attempt
line of GetElementValue
, I'm trying to go from string -> object -> TElementType. Unfortunately, this does not work for an integer test case. When running the following test:
[Test]
public void GetElementValueShouldReturnValueOfIntegerElementAsInteger()
{
const int expectedValue = 5;
const string elementName = "intProp";
var xElement = new XElement("name");
var integerElement = new XElement(elementName) { Value = expectedValue.ToString() };
xElement.Add(integerElement);
int value = XElementExtensions.GetElementValue<int>(xElement, elementName);
Assert.AreEqual(expectedValue, value, "Expected integer value was not returned from element.");
}
I get the following exception when GetElementValue<int>
is called:
System.InvalidCastException : Cannot cast element value '5' to type 'Int32'.
Am I going to have to handle each casting case (or at least the numeric ones) separately?
You could also try the Convert.ChangeType
Convert.ChangeType(element.Value, typeof(TElementType))