Mat*_*ero 2 .net c# linq generics casting
我正在努力完成以下任务.
假设我有这个数据模型:
public class Article
{
public ICollection<string> Tags { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
从数据库中检索这些标记.我的数据库的API将它们作为一个返回给我List<object>.
因此,我需要转换为List<object>实现的东西ICollection<string>.
我知道LINQ Cast<T>()方法将其元素强制转换为给定类型并返回转换后的元素IEnumerable<T>.
但是,我不能使用Cast<string>(),因为总是会投我List<object>来IEnumerable<string>,不给该车型有任何选项ICollection<double>属性(或任何其他类型).
我可以使用反射并获取泛型类型参数:
Type genericArg = collectionType.GetGenericArguments().First();
Run Code Online (Sandbox Code Playgroud)
但这会让我Type失去运行时间,我无法使用它Cast<genericArg>().
我怎样才能施放IEnumerable<object>一个IEnumerable动态的Type?
我应该注意,我的模型上不允许复杂的类型,所以像:
public ICollection<Tag> Tags { get; set; }
Run Code Online (Sandbox Code Playgroud)
不会发生.我只处理原始类型.
你对铸造有一个基本的误解.
必须在编译时知道转换操作的结果类型.¹
请考虑以下示例:
string a = "abc";
object b = (object)a;
string c = (string)b;
Run Code Online (Sandbox Code Playgroud)
在运行时类型的a,b并且c是相同的.是的string.在编译时类型是不同的.转换仅与编译时类型相关.
因此,你的问题的答案
如何投射
IEnumerable<object>到IEnumerable<runtime type>
是:你没有.对于运行时类型,强制转换没有意义.
也就是说,让我为你的真正问题提供一个解决方案:假设你有一个IEnumerable<object> values,Type myTargetType并且想要创建一个List<typeof(myTargetType)>包含值的方法.
首先,使用反射创建列表:
var listType = typeof(List<>).MakeGenericType(myTargetType);
IList myList = (IList)Activator.CreateInstance(listType);
Run Code Online (Sandbox Code Playgroud)
然后你填写清单:
foreach (var item in values)
{
myList.Add(item);
}
Run Code Online (Sandbox Code Playgroud)
显然,Add将引发ArgumentException如果一个条目values是不是运行时类型myTargetType.
¹结果类型可以是泛型类型,但也必须在编译时指定泛型类型参数.
| 归档时间: |
|
| 查看次数: |
3520 次 |
| 最近记录: |