Estoy tratando de escribir un método genérico para obtener un valor XElement
de una manera fuertemente tipada. Aquí es lo que tengo:Cómo convertir a parámetro genérico en C#?
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);
}
}
}
Como se puede ver en la línea de GetElementValue
First attempt
, estoy tratando de pasar de la cadena -> objeto -> TElementType. Desafortunadamente, esto no funciona para un caso de prueba entero. Cuando se ejecuta la siguiente prueba:
[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.");
}
me sale el siguiente excepción cuando GetElementValue<int>
se llama:
System.InvalidCastException : Cannot cast element value '5' to type 'Int32'.
¿Voy a tener que manejar cada caso fundición (o al menos los numéricos) por separado?
Esto funciona para mí. 'ChangeType' devuelve un objeto fijo, pero el molde implícito ahora funciona. Además, ahora compruebo para 'FormatException' en lugar de' InvalidCastException' en el bloque 'try/catch'. Respuesta corta y simple. – Scott
Tras una investigación adicional, no puede usar esto con tipos anulables. Entonces, usando este artículo: http://aspalliance.com/852 escribí un método de extensión para manejar ambos tipos. – Scott