Convert.ChangeType 为 nullable int 抛出无效的强制转换异常

win*_*yip 4 c#

如果我调用下面的 GetClaimValue 方法,其中 T 是可为 null 的 int,则会出现无效的强制转换异常。

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);
}
Run Code Online (Sandbox Code Playgroud)

例如:

 GetClaimValue<int?>(IdentityServer.CustomClaimTypes.SupplierId, claims)
Run Code Online (Sandbox Code Playgroud)

有人知道解决这个问题的方法吗?

Chr*_*air 7

我假设Claim.Valueis 类型Object并且您在这里动态转换,您不能直接将 an 转换intint?via Convert.ChangeType

一种选择是使用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);
}
Run Code Online (Sandbox Code Playgroud)


Jam*_*mes 6

我无法解释为什么它会抛出异常,但是当我使用Convert.ChangeType.

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

var converter = TypeDescriptor.GetConverter(typeof(T));
return (T)converter.ConvertFrom(claim.Value);
Run Code Online (Sandbox Code Playgroud)