当前位置:  开发笔记 > 编程语言 > 正文

如何将IEnumerable <?>转换为IEnumerable <string>?

如何解决《如何将IEnumerable<?>转换为IEnumerable<string>?》经验,为你挑选了1个好方法。

这个问题已完全编辑.要查看原始版本,请参阅编辑历史记录


我想我应该解释一下我的情况和问题的背景.

我正在检查使用自定义属性注释的属性的类型.然后我得到该属性的值,但作为object:

IEnumerable propertiesValues = myType.GetProperties().Where(p => p.GetCustomAttributes(typeof(MyCustomAttribute)) != null);


一旦我有这些值,我想Map在他们身上调用我的方法,根据他们的类型将它们转换为不同的对象.这是因为我的数据库API需要这样做.

foreach(object value in propertiesValues)
{
     object mapped = Map(value);
     // ...
}

我需要所有的IEnumerable价值,要转换成IEnumerable.所以我的第一个方法是:

public static object Map(object value)
{
    if(value is IEnumerable || value is IEnumerable || ....)
         return ((IEnumerable) value).Cast();
}


但是,这会引发运行时异常,例如我无法强制IEnumerable转换IEnumerable.



1> Eric Lippert..:

您想要的功能称为协方差,IEnumerable只有当类型参数都是引用类型时,C#才支持它.也就是说,IEnumerable可以转换为IEnumerable,但IEnumerable可能不会如此转换.

原因是:当您获得一系列字符串时,这些字符串引用已经是合法的对象引用.但是当一个int被装箱时,它只会成为一个合法的对象引用; 编译器在哪里可以插入装箱操作?它没有,所以转换是非法的.

要转换IEnumerableIEnumerable你必须通过投影明确地进行拳击:

from number in items select (object)item

要么

items.Select(item => (object) item)

那将是IEnumerable,然后你可以做你喜欢的事情.

或者使用Cast序列运算符

items.Cast()


它做同样的事情.或使用其查询表单:

from object item in items select item

或者只是使用非泛型IEnumerable,它给出一系列盒装值,如果实际上它是一个结构序列.

我注意到,虽然你的,然后浇注计划IEnumerable,以IEnumerable通过Cast扩展方法是注定要失败的.这些物品将是盒装的.盒装的int不能拆箱到字符串.

看起来你在这里打击类型系统而不是使用它.也许您应该描述您的真实问题,而不是您尝试围绕类型系统进行最终运行来解决它.


@moarboilerplate:对; 在您查询类型参数的类型参数时,您的代码不再是*generic*.通用代码适用于所有可能的类型; 这就是它被称为"通用"的原因.
推荐阅读
雨天是最美
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有