A.B*_*.B. -1 .net c# linq boxing
装箱T只能拆箱到T。例如,这不起作用:
object o1 = 5;
double n3 = (double)o1;
Run Code Online (Sandbox Code Playgroud)
Cast()在 a 上使用 Linq 的方法List<T>会引发类似的异常:
List<int> _numbers = new List<int>() { 1, 2, 3, 4 };
// this is also not working
IEnumerable<double> nums = _numbers.Cast<double>();
Run Code Online (Sandbox Code Playgroud)
List<T>被装箱?List<>不创建列表副本的情况下转换每个元素?Select()方法发布任何答案,因为它正在创建集合的副本)我们在这里只讨论值类型。引用类型遵循不同的规则。
List<T>被装箱?不。Java 会这样做,T在运行时擦除所有类型并将所有类型重定向到单个List<Object>实现(称为类型擦除)。在 .NET 中,对于值类型, every List<ValueType1>, List<ValueType2>,List<ValueType3>在运行时接收不同的实现(请参阅此处)。
List<>不创建列表副本的情况下转换每个元素?当您将值类型转换为其他内容时,您正在制作它的副本。经常在堆栈上,但副本存在。您不能简单地将值类型作为不同的值类型来访问。
例如:
public static void M1(long n) {
M2((int)n);
}
public static void M2(int n) {
}
Run Code Online (Sandbox Code Playgroud)
在 IL asm 中被翻译成
IL_0000: ldarg.0
IL_0001: conv.i4
IL_0002: call void C::M2(int32)
IL_0007: ret
Run Code Online (Sandbox Code Playgroud)
哪里conv.i4:
如果转换成功,则将结果值压入堆栈。
请注意,即使取出的元素也会List<int>导致复制:您没有访问 INSIDE 中的元素List<int>:
public void M1(List<int> a) {
int v = a[0];
v = 6; // this won't modify a[0]
}
Run Code Online (Sandbox Code Playgroud)
使用数组(以及更新的 C#),您可以直接访问数组的元素:
public void M1(int[] a) {
ref int r = ref a[0];
r = 6; // this will modify a[0]
}
Run Code Online (Sandbox Code Playgroud)
这里的区别是,索引器List<T>(当你做出一个被调用的事情var foo = list[5]是一种方法,而阵列的索引是(阵列在.NET虚拟机的最低水平所定义的IL指令,并且具有处理它们的特殊 OPList<T>构建在数组的“顶部”)。即使在SharpLab上也可以很容易地看到这一点。
| 归档时间: |
|
| 查看次数: |
101 次 |
| 最近记录: |