如何在C#中转换为通用参数?

时间:2010-10-07 11:25:00

标签: c# generics casting linq-to-xml xelement

我正在尝试编写一种以强类型方式获取XElement值的泛型方法。这就是我所拥有的:

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

正如您在First attempt的{​​{1}}行中看到的那样,我正试图从字符串 - >&gt;对象 - &gt; TElementType。不幸的是,这不适用于整数测试用例。运行以下测试时:

GetElementValue

调用[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."); } 时出现以下异常:

  

System.InvalidCastException:无法将元素值'5'强制转换为'Int32'。

我是否必须分别处理每个铸造案例(或至少是数字铸造案例?)

5 个答案:

答案 0 :(得分:11)

您也可以尝试Convert.ChangeType

Convert.ChangeType(element.Value, typeof(TElementType))

答案 1 :(得分:3)

从您的代码中,而不是:

return (TElementType)((object) element.Value);
你会这样做:

return (TElementType) Convert.ChangeType(element.Value, typeof (T));

这里唯一需要注意的是TElementType必须实现IConvertible。但是,如果你只是谈论内在类型,那么它们都已经实现了。

对于您的自定义类型,假设您在此处需要它们,则必须拥有自己的转换。

答案 2 :(得分:2)

您无法进行从StringInt32的隐式或显式投射,您需要使用Int32的{​​{1}}或Parse方法。您可以创建一些漂亮的扩展方法,例如:

TryParse

我经常使用这些。

答案 3 :(得分:1)

在C#中,您无法将字符串对象强制转换为Int32。例如,此代码产生编译错误:

    string a = "123.4";
    int x = (int) a;

如果您需要此类功能,请尝试使用Convert classInt32.ParseInt32.TryParse方法。
是的,如果要将字符串转换为int,则应单独处理数值转换。

答案 4 :(得分:0)

string也实现了IConvertible,因此您可以执行以下操作。

((IConvertible)mystring).ToInt32(null);

你甚至可以在它周围抛出一些扩展方法,使它更清洁。