将字符串强制转换为 IEnumerable

本文关键字:IEnumerable object 转换 字符串 | 更新日期: 2023-09-27 18:27:40

我有propertyValue,这是一个传递给我的函数的对象。

我可以假设这是某种IEnumerable,但是由于接口合约,我必须将其作为object而不是直接作为IEnumerable接受。

当我尝试将我的值转换为IEnumerable<object>,以便我可以得到长度时,我得到了一个InvalidCastException

var length = ((IEnumerable<object>) propertyValue).Cast<object>().Count();

我得到以下异常:

System.InvalidCastException: 无法强制转换类型的对象 要键入的"系统字符串" 'System.Collections.Generic.IEnumerable'1[System.Object]'.

将字符串强制转换为 IEnumerable<object>

IEnumerable<T> 接口是协变的,但协方差不适用于值类型。将值类型强制转换为引用类型会更改表示形式 - 需要对值进行装箱,并返回对装箱值的引用。强制转换引用类型不会更改表示形式 - 它仍然是相同的引用,引用相同的对象。

stringIEnumerable<char>,所以不能投射到IEnumerable<object>

如其他答案所述,解决方案是转换为非泛型IEnumerable

var length = ((IEnumerable) propertyValue).Cast<object>().Count();

我已经通过简单地转换为IEnumerable而不是转换为IEnumerable<object>来解决此问题。

var length = ((IEnumerable) propertyValue).Cast<object>().Count();

String 实现 IEnumerable<char> 接口,可以将其强制转换为此接口

var length = ((IEnumerable<char>) propertyValue).Count();

对于未知类型的集合,可以使用自己的扩展方法将其强制转换为 IEnumerable 和下一个枚举值。

static class EnumerableExtensions
{
    public static int Count(this IEnumerable source)
    {
        int res = 0;
        foreach (var item in source)
            res++;
        return res;
    }
}
var collection = propertyValue as IEnumerable;
if(collection != null)
{
    var length = collection.Count();
}

使用 Cast(( 方法将导致值类型的装箱,并且对于大型集合可能会有性能问题。

以下代码实际上应该可以满足您的需求

var length = (propertyValue as IEnumerable<object>).Count();