Convert.ChangeType 生成具体类型元素的数组,而不是对象

本文关键字:数组 对象 元素 ChangeType 类型 Convert | 更新日期: 2023-09-27 17:57:11

正在努力解决以下问题。我有一个定义数据库表中键名称的属性。使用反射,我初始化具有该属性的属性或字段的值。一切都很好,直到我将我的属性定义为数组:

[ConfigurationKey("TestArray")]
public int[] Array { get; set; }

假设存储在表中的值是逗号分隔的字符串,我使用以下方法来创建一个数组:

return valueString.Split(',').Select(s => Convert.ChangeType(s, memberType.GetElementType())).ToArray();

这确实会创建一个元素数组,但只创建一个对象数组。因此,当我使用 FieldInfo 或 PropertyInfo 设置值时,它会抛出异常"无法将Object[]分配给Int32[]"。

有什么想法吗?

Convert.ChangeType 生成具体类型元素的数组,而不是对象

鉴于Convert.ChangeType被声明为返回Object,我认为这并不特别令人惊讶。 ToArray()将创建一个与输入序列具有相同元素类型的数组,在这种情况下,Select将返回一个IEnumerable<object>

一种选择是使用反射调用Cast(然后调用ToArray)。老实说,将所有内容放入单个泛型方法中可能是最简单的,并通过反射调用

public static T[] ParseToArray<T>(string valueString)
{
    return valueString.Split(',')
                      .Select(s => (T) Convert.ChangeType(s, typeof(T))
                      .ToArray();
}

然后,您需要:

Type t = memberType.GetElementType();
// Use the type declaring ParseToArray here
MethodInfo methodDefinition = typeof(...).GetMethod("ParseToArray");
MethodInfo method = methodDefinition.MakeGenericMethod(t);
object array = method.Invoke(null, new object[] { valueString });