ImmutableArray的CastUp、As与CastArray方法差异及用法咨询
ImmutableArray三个转换方法的差异与场景解析
核心疑问确认:CastUp是否复用底层数组
你的理解完全正确:ImmutableArray<T>.CastUp<TDerived> 用于向上转换(派生类型→基类型/接口)时,直接复用底层数组实例,不会产生任何内存分配。因为向上转换是类型安全的,CLR允许将派生类型的数组直接当作基类型数组引用,比如Foo[]可以直接被视为IFoo[],所以不需要复制数组元素。
三个方法的详细差异与预期用法
1. 静态方法 ImmutableArray<T>.CastUp<TDerived>
- 用途:专门用于向上类型转换(从
TDerived派生类型转换到T基类型/接口) - 约束:编译时强制检查
TDerived是否是T的派生类型或实现了T接口,确保类型安全 - 性能:O(1)时间复杂度,无内存分配,直接复用原数组
- 示例:
ImmutableArray<Foo> fooArray = ImmutableArray.Create(new Foo()); ImmutableArray<IFoo> interfaceArray = ImmutableArray<IFoo>.CastUp<Foo>(fooArray);
2. 实例方法 ImmutableArray<T>.As<TOther>
- 用途:用于引用兼容的类型转换,包括向上转换、向下转换,或者同一类型的转换
- 特点:同样复用底层数组,无内存分配,但类型兼容性仅在运行时验证;如果数组中存在无法转换为
TOther的元素,会抛出InvalidCastException - 预期场景:当你明确知道整个数组的元素都可以安全转换为目标类型时使用,比如已知
ImmutableArray<IFoo>实际存储的都是Foo实例,可用于向下转换 - 示例:
// 向上转换(等价于CastUp,但写法更灵活) ImmutableArray<IFoo> interfaceArray = fooArray.As<IFoo>(); // 向下转换(需确保所有元素都是Foo类型) ImmutableArray<Foo> fooArray2 = interfaceArray.As<Foo>();
3. 实例方法 ImmutableArray<T>.CastArray<TOther>
- 用途:支持所有类型转换场景,包括非引用兼容的转换(如值类型装箱/拆箱、自定义类型转换),以及需要逐个元素验证的向下转换
- 特点:返回的
ImmutableArray<TOther>底层是一个延迟枚举的包装,首次访问元素时会逐个执行转换操作;如果元素转换失败,会抛出InvalidCastException - 性能:首次访问时为O(n)时间复杂度,可能产生内存分配(比如值类型装箱)
- 示例:
// 值类型装箱转换 ImmutableArray<int> intArray = ImmutableArray.Create(1,2,3); ImmutableArray<object> objArray = intArray.CastArray<object>(); // 向下转换(逐个元素检查) ImmutableArray<object> mixedArray = ImmutableArray.Create<object>("test", 123); ImmutableArray<string> stringArray = mixedArray.CastArray<string>(); // 运行时会抛异常,因为存在int元素
As与CastArray的核心区别
- 内存与性能:
As无分配、O(1);CastArray是延迟枚举,首次访问O(n),可能分配内存 - 转换范围:
As仅支持引用兼容的转换;CastArray支持所有类型转换(包括装箱、自定义转换) - 验证时机:
As在转换时(或首次访问元素时)检查整个数组的类型兼容性;CastArray逐个元素检查转换
关于向下转换的说明
As可以用于向下转换,但要求整个数组的元素都属于目标类型,运行时验证失败会抛异常,无内存分配CastArray也支持向下转换,会逐个元素执行转换,适用于需要处理非引用兼容转换或不确定所有元素类型的场景
内容的提问来源于stack exchange,提问作者Enrico Massone
相关产品推荐
相关产品推荐

