将 List<object> 转换为运行时已知的某种类型的列表
Convert List<object> to List of some type known at runtime
我正在尝试将逗号分隔的字符串转换为某种类型的列表。
private static void SetPropertyValue(this object obj, PropertyInfo propInfo, object value)
{
if (propInfo.PropertyType != typeof(string) && typeof(IEnumerable).IsAssignableFrom(propInfo.PropertyType))
{
var listType = propInfo.PropertyType.GetCollectionType();
var listValue = value.ToString().Split(',').Select(x => Convert.ChangeType(x, listType, null)).ToList();
propInfo.SetValue(obj, listValue, null);
}
//....
}
public static Type GetCollectionType(this Type type)
{
foreach (Type interfaceType in type.GetInterfaces())
{
if (interfaceType.IsGenericType &&
interfaceType.GetGenericTypeDefinition()
== typeof(IList<>))
{
return type.GetGenericArguments()[0];
}
}
throw new ArgumentException("Message is irrelevant");
}
拆分字符串并使用 Convert.ChangeType 转换每个值效果很好,但会创建 List<object>
。我需要某种方法来生成 List<PropType>
以便 SetValue 调用正常工作。
如果您使用 List<string>
属性 运行 此代码,您将收到 ArgumentException,因为 List<object>
无法转换为 List<string>
.
我通过让我的 SetPropertyValue 方法接受泛型类型 T
并创建 List<T>
.
来解决这个问题
public static void SetPropertyValue<T>(object obj, PropertyInfo propInfo, object value)
{
if (propInfo.PropertyType != typeof(string) && typeof(IEnumerable).IsAssignableFrom(propInfo.PropertyType))
{
List<T> listValue = value.ToString()
.Split(',')
.Select(x => (T)Convert.ChangeType(x, typeof(T), null))
.ToList();
propInfo.SetValue(obj, listValue, null);
}
// ...
}
然后我可以使用反射调用方法以将 Type 变量作为 T
传递。
var type = property.PropertyType.GetCollectionType();
var method = typeof(TypeExtensions).GetMethod(nameof(TypeExtensions.SetPropertyValue));
var generic = method.MakeGenericMethod(type);
generic.Invoke(obj, new object[] { obj, property, value });
我正在尝试将逗号分隔的字符串转换为某种类型的列表。
private static void SetPropertyValue(this object obj, PropertyInfo propInfo, object value)
{
if (propInfo.PropertyType != typeof(string) && typeof(IEnumerable).IsAssignableFrom(propInfo.PropertyType))
{
var listType = propInfo.PropertyType.GetCollectionType();
var listValue = value.ToString().Split(',').Select(x => Convert.ChangeType(x, listType, null)).ToList();
propInfo.SetValue(obj, listValue, null);
}
//....
}
public static Type GetCollectionType(this Type type)
{
foreach (Type interfaceType in type.GetInterfaces())
{
if (interfaceType.IsGenericType &&
interfaceType.GetGenericTypeDefinition()
== typeof(IList<>))
{
return type.GetGenericArguments()[0];
}
}
throw new ArgumentException("Message is irrelevant");
}
拆分字符串并使用 Convert.ChangeType 转换每个值效果很好,但会创建 List<object>
。我需要某种方法来生成 List<PropType>
以便 SetValue 调用正常工作。
如果您使用 List<string>
属性 运行 此代码,您将收到 ArgumentException,因为 List<object>
无法转换为 List<string>
.
我通过让我的 SetPropertyValue 方法接受泛型类型 T
并创建 List<T>
.
public static void SetPropertyValue<T>(object obj, PropertyInfo propInfo, object value)
{
if (propInfo.PropertyType != typeof(string) && typeof(IEnumerable).IsAssignableFrom(propInfo.PropertyType))
{
List<T> listValue = value.ToString()
.Split(',')
.Select(x => (T)Convert.ChangeType(x, typeof(T), null))
.ToList();
propInfo.SetValue(obj, listValue, null);
}
// ...
}
然后我可以使用反射调用方法以将 Type 变量作为 T
传递。
var type = property.PropertyType.GetCollectionType();
var method = typeof(TypeExtensions).GetMethod(nameof(TypeExtensions.SetPropertyValue));
var generic = method.MakeGenericMethod(type);
generic.Invoke(obj, new object[] { obj, property, value });