超全模态模型 × Harness 升级,升级解锁 ArkClaw,最新支持 DeepSeek-V4 系列与 GLM-5.1
IEnumerable<object>
运行以下程序会得到如下输出:
Class is object. Class list is IEnumerable. Struct is object. Struct list is not IEnumerable. 这表明结构体实例可以被视为object类型,但结构体实例的列表却不能被视为IEnumerable<object>。这是为什么?测试代码 #using System; using System.Collections.Generic; public class Program { public struct MyStruct {} public class MyClass {} public static void Main() { // 检查类实例是否属于object类型 MyClass classInstance = new MyClass(); if (classInstance is object) Console.WriteLine("Class is object."); else Console.WriteLine("Class is no object."); // 检查类实例列表是否属于IEnumerable<object> List<MyClass> classList = new List<MyClass>() {classInstance}; if (classList is IEnumerable<object>) Console.WriteLine("Class list is IEnumerable<object>"); else Console.WriteLine("Class list is not IEnumerable<object>"); // 检查结构体实例是否属于object类型 MyStruct structInstance = new MyStruct(); if (structInstance is object) Console.WriteLine("Struct is object."); else Console.WriteLine("Struct is no object."); // 检查结构体列表是否属于IEnumerable<object> List<MyStruct> structList = new List<MyStruct>() {structInstance}; if (structList is IEnumerable<object>) Console.WriteLine("Struct list is IEnumerable<object>"); else Console.WriteLine("Struct list is not IEnumerable<object>"); Console.ReadLine(); } } 原因分析 #单个值类型的装箱操作 结构体是值类型,object是所有.NET类型的基类。当把单个值类型实例和object做类型检查时,CLR会自动执行装箱操作:把值类型的数据复制到堆上的对象实例中,因此structInstance is object会返回true。泛型协变的类型限制IEnumerable<T>是带out T标记的协变泛型接口,协变允许将IEnumerable<派生类型>隐式转换为IEnumerable<基类型>,但这个特性只支持引用类型,不支持值类型:对于引用类型MyClass,List<MyClass>实现了IEnumerable<MyClass>,由于协变特性,它可以直接被视为IEnumerable<object>——毕竟引用类型的转换只是指向对象的引用变化,不需要复制数据。对于值类型MyStruct,如果要让List<MyStruct>转为IEnumerable<object>,意味着列表里的每个元素都需要单独装箱,但协变机制无法自动完成这种批量转换(会带来额外性能开销和类型安全风险),因此CLR直接禁止了值类型的协变转换,所以structList is IEnumerable<object>返回false。如果需要把结构体列表转为IEnumerable<object>,可以手动调用Cast<object>()方法完成批量装箱:if (structList.Cast<object>() is IEnumerable<object>) Console.WriteLine("Struct list can be cast to IEnumerable<object>"); 内容的提问来源于stack exchange,提问作者Amos Egel
这表明结构体实例可以被视为object类型,但结构体实例的列表却不能被视为IEnumerable<object>。这是为什么?
object
using System; using System.Collections.Generic; public class Program { public struct MyStruct {} public class MyClass {} public static void Main() { // 检查类实例是否属于object类型 MyClass classInstance = new MyClass(); if (classInstance is object) Console.WriteLine("Class is object."); else Console.WriteLine("Class is no object."); // 检查类实例列表是否属于IEnumerable<object> List<MyClass> classList = new List<MyClass>() {classInstance}; if (classList is IEnumerable<object>) Console.WriteLine("Class list is IEnumerable<object>"); else Console.WriteLine("Class list is not IEnumerable<object>"); // 检查结构体实例是否属于object类型 MyStruct structInstance = new MyStruct(); if (structInstance is object) Console.WriteLine("Struct is object."); else Console.WriteLine("Struct is no object."); // 检查结构体列表是否属于IEnumerable<object> List<MyStruct> structList = new List<MyStruct>() {structInstance}; if (structList is IEnumerable<object>) Console.WriteLine("Struct list is IEnumerable<object>"); else Console.WriteLine("Struct list is not IEnumerable<object>"); Console.ReadLine(); } }
单个值类型的装箱操作 结构体是值类型,object是所有.NET类型的基类。当把单个值类型实例和object做类型检查时,CLR会自动执行装箱操作:把值类型的数据复制到堆上的对象实例中,因此structInstance is object会返回true。
structInstance is object
true
泛型协变的类型限制IEnumerable<T>是带out T标记的协变泛型接口,协变允许将IEnumerable<派生类型>隐式转换为IEnumerable<基类型>,但这个特性只支持引用类型,不支持值类型:
IEnumerable<T>
out T
IEnumerable<派生类型>
IEnumerable<基类型>
MyClass
List<MyClass>
IEnumerable<MyClass>
MyStruct
List<MyStruct>
structList is IEnumerable<object>
false
如果需要把结构体列表转为IEnumerable<object>,可以手动调用Cast<object>()方法完成批量装箱:
Cast<object>()
if (structList.Cast<object>() is IEnumerable<object>) Console.WriteLine("Struct list can be cast to IEnumerable<object>");
内容的提问来源于stack exchange,提问作者Amos Egel
超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起
模型再升级,30秒超长叙事, 模态参考扩容
模型自由,工具不限,最新支持 Deepseek-V4 系列、GLM-5.3 系列
超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列
大模型19元起,Al应用9.9元畅享,新人首购爆款尽享优惠