可空整数类型的 Convert.ChangeType 抛出无效转换异常

4
如果我在下面调用GetClaimValue方法,其中T是可空整数,会出现无效的强制转换异常。
private static T GetClaimValue<T>(string claimType, IEnumerable<Claim> claims)
{
    var claim = claims.SingleOrDefault(c => c.Type == claimType);

    if (claim != null)
        return (T) Convert.ChangeType(claim.Value, typeof(T));

    return default(T);
}

例如:
 GetClaimValue<int?>(IdentityServer.CustomClaimTypes.SupplierId, claims)

有人知道如何解决这个问题吗?

完整的异常信息,请。 - pm100
claim.Value 是什么类型? - pm100
claim.Value将始终是一个字符串,但可能为空字符串。 - wingyip
阅读源代码 https://referencesource.microsoft.com/#mscorlib/system/convert.cs,3bcca7a9bda4114e,似乎无法将其转换为int? - pm100
2个回答

6
我假设Claim.ValueObject类型,您正在进行动态转换的过程中,您不能直接通过Convert.ChangeTypeint转换为int?
一种选择是使用Nullable.GetUnderlyingType,它将检查是否为可空结构体案例,先通过底层数据类型进行转换,然后再强制转换为T
您还需要处理null情况。
if (claim != null)
{
    var conversionType = typeof(T);

    if (Nullable.GetUnderlyingType(conversionType) != null)
    {
        if (claim.Value == null) //check the null case!
            return default(T);

        //use conversion to `int` instead if `int?`
        conversionType = Nullable.GetUnderlyingType(conversionType);
    }

    return (T)Convert.ChangeType(claim.Value, conversionType);
}

5

我无法解释为什么会抛出异常,但是我在使用Convert.ChangeType时遇到过类似的情况。

试着先获取传入类型的转换器,然后使用该转换器进行转换。我使用这种方法得到了更好的结果。

var converter = TypeDescriptor.GetConverter(typeof(T));
return (T)converter.ConvertFrom(claim.Value);

1
这是一个非常棒的答案,解决了我的问题。谢谢! - Westley Bennett

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接