- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我已阅读 this excellent question关于如何定期int[]
在 foreach
下处理(框与否)循环。
Array
确实实现了非泛型 IEnumerable
所以它必须使用 object
内部(而不是 int
)
但它turns out那 - 在运行时它实际上被处理为 IEnumerable<T>
如何通过简单的 C#
测试/证明(没有拳击)它代码? (而不是通过阅读 IL。)
最佳答案
我喜欢@phoog 的回答,所以只是为了好玩:)
助手类
public static class ILUtils
{
private static Dictionary<short, OpCode> s_opcodes = new Dictionary<short, OpCode>();
static ILUtils()
{
FieldInfo[] opCodeFields = typeof(OpCodes).GetFields(BindingFlags.Public | BindingFlags.Static);
foreach (FieldInfo opCodeField in opCodeFields)
{
if (opCodeField.FieldType != typeof(OpCode))
continue;
OpCode opcode = (OpCode)opCodeField.GetValue(null);
s_opcodes.Add(opcode.Value, opcode);
}
}
public static bool ContainsOpcodes(MethodInfo methodInfo, IEnumerable<OpCode> targetOpCodes)
{
MethodBody methodBody = methodInfo.GetMethodBody();
using (BinaryReader ilReader = new BinaryReader(new MemoryStream(methodBody.GetILAsByteArray())))
{
while (ilReader.BaseStream.Position < ilReader.BaseStream.Length)
{
short opCodeValue = ilReader.ReadByte();
if (opCodeValue == 0xfe)
opCodeValue = (short)(opCodeValue << 8 | ilReader.ReadByte());
OpCode opCode = s_opcodes[opCodeValue];
if (targetOpCodes.Contains(opCode))
return true;
int argumentSize = 4;
if (opCode.OperandType == OperandType.InlineNone)
argumentSize = 0;
else if (opCode.OperandType == OperandType.ShortInlineBrTarget || opCode.OperandType == OperandType.ShortInlineI || opCode.OperandType == OperandType.ShortInlineVar)
argumentSize = 1;
else if (opCode.OperandType == OperandType.InlineVar)
argumentSize = 2;
else if (opCode.OperandType == OperandType.InlineI8 || opCode.OperandType == OperandType.InlineR)
argumentSize = 8;
else if (opCode.OperandType == OperandType.InlineSwitch)
{
int num = ilReader.ReadInt32();
argumentSize = (int)(4 * num + 4);
}
ilReader.BaseStream.Position += argumentSize;
}
}
return false;
}
}
使用示例
private static void BoxingForEach()
{
IEnumerable foo = (IEnumerable)new int[10];
foreach (int i in foo) ;
}
private static void NoBoxingForEach()
{
int[] foo = new int[10];
foreach (int i in foo) ;
}
static void Main(string[] args)
{
MethodInfo boxingForEach = typeof(Program).GetMethod("BoxingForEach", BindingFlags.Static | BindingFlags.NonPublic);
MethodInfo noBoxingForEach = typeof(Program).GetMethod("NoBoxingForEach", BindingFlags.Static | BindingFlags.NonPublic);
Console.WriteLine("BoxingForEach is using boxing: {0}",
ILUtils.ContainsOpcodes(boxingForEach, new[] { OpCodes.Box, OpCodes.Unbox, OpCodes.Unbox_Any }));
Console.WriteLine("NoBoxingForEach is using boxing: {0}",
ILUtils.ContainsOpcodes(noBoxingForEach, new[] { OpCodes.Box, OpCodes.Unbox, OpCodes.Unbox_Any }));
}
结果
BoxingForEach is using boxing: True
NoBoxingForEach is using boxing: False
关于c# - 在常规阵列上测试 foreach 框/拆箱?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14038264/
对于数字密集型代码,我编写了一个具有以下签名的函数: def update( f: (Int,Int,Double) => Double ): Unit = {...} 但是,因为 Function3
鉴于此代码更改: int count = 0; 替换为: int count = NumberUtils.INTEGER_ZERO; 我依靠 Apache NumberUtils 进行更改,只是为了常
我有兴趣在我的解决方案中找到所有发生装箱或拆箱的地方。我知道我可以像这样使用 ildasm: Ildasm.exe yourcomponent.dll /text | findstr box 但我不想
我目前正在努力研究选角和拳击。据我目前了解: 装箱 - 值类型到引用类型(即 int 到对象) 拆箱 - 引用类型到值类型(即对象到 int) Type Casting - 目前在我看来类似于拳击但允
自动装箱/拆箱是编译器还是运行时? 考虑以下示例: public Integer get() { return 1; //(1) } 在 (1) 处,原始整数值将被转换为类似于 new In
试图说服某人从 .NET 1.1 切换 我看到有人说在 .NET 1.1 之后使用 Dictionary 类的一个优点是性能提高,因为不必拆箱/转换对象。除此之外还有其他改进吗? 或者离开 .NET
大家可以向我解释一下 new 的性质以及 Integer 的使用 Integer i = new Integer(-10); Integer j = new Integer(-10); Integer
public IList A23 { get; set; } s.A23 = new List(new int[] { 62, 63, 64 }); IList g = s.A23; double d
如果我有一个包含 Object 的列表,如下所示: List t = new List(); t.Add(10); t.Add("xyx"); 在这种情况下,如果我取回列表项,是否需要将它们拆箱? 最
最近在学习值类型,有点迷茫。此外,转换和拆箱都使用相同的语法 - (expected type)(object),对吧?那么类型之间的简单转换呢,即强制转换或只是转换? int x = (int)2.
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我正在使用 NSJSONSerialization 将 JSON 文档转换为 Core Foundation 类型。 我的 JSON 中有一个字段,它是一个“数字”。它有时是整数,有时是 float
我已阅读 this excellent question关于如何定期int[]在 foreach 下处理(框与否)循环。 Array确实实现了非泛型 IEnumerable所以它必须使用 object
在对 this question 的公认最佳回复中,有一个明确的解释为什么拳击会发生。 但是,如果我反编译代码(使用 java 反编译器),我看不到 scala.runtime.BoxesRunTim
根据最近的即席建议,关于如何让 Scala 通过查看字节码告诉我是否正在进行拳击,我创建了这个类: class X { def foo(ls : Array[Long]) = ls map (_.to
在一些代码中我看到了这个: private void compute(Long a, Long b, Long c) { long result = a-(b+c); ... 结果存储
我的 Sonar 6.7.1 LTS 实例无法识别以下代码中的 NullPointerException: public static boolean getBooleanFromMap() {
我发现 float 和 double 在不同情况下有后缀。那么 float 的后缀 F 和 f, double 的后缀 D 和 d 有什么区别?有这种行为的历史吗? 还有关于类型构造函数的问题,例如
我很想知道 C# 中的所有强制转换是否都会导致装箱,如果不是,所有强制转换都是代价高昂的操作吗? 示例取自 Boxing and Unboxing (C# Programming Guide)
这个问题在这里已经有了答案: 关闭 9 年前。 Possible Duplicate: Structs, Interfaces and Boxing 来自 MSDN:http://msdn.micr
我是一名优秀的程序员,十分优秀!