我意识到没有人会坐下来直接用IL开发软件(是吗?).但是假设您想与其他人共享一段IL代码(例如,由C#编译器输出)以供讨论,而且您想要用一些注释来注释它.在IL中是否有实际的注释语法,以便您可以在不将文本作为IL无效的情况下执行此操作?没什么大不了的,只是好奇.
今天我正在使用Entity Framework,我已经读过为C#创建的IL与以下代码的VB.NET不同:
VB.NET:
Dim ctx As New TravelEntities
Sub Main()
CallContext()
CallContext()
CallContext()
End Sub
Private Sub CallContext()
Dim someCustomer = From x In ctx.Customer
Where x.CustomerId.Equals(5)
Select x
Console.WriteLine(someCustomer.Count())
End Sub
Run Code Online (Sandbox Code Playgroud)
C#:
private static TravelEntities ctx = new TravelEntities();
static void Main(string[] args)
{
CallContext();
CallContext();
CallContext();
}
private static void CallContext()
{
var someCustomer = from x in ctx.Customer
where x.CustomerId.Equals(5)
select x;
Console.WriteLine(someCustomer.Count());
}
Run Code Online (Sandbox Code Playgroud)
他们产生以下IL:
VB:
.method private static void CallContext() cil managed
{
// Code size …Run Code Online (Sandbox Code Playgroud) 如果我的方法Multiply定义为:
public static class Experiment
{
public static int Multiply(int a, int b)
{
return a * b;
}
}
Run Code Online (Sandbox Code Playgroud)
那么为什么编译器会发出这个IL:
.method public hidebysig static int32 Multiply(int32 a, int32 b) cil managed
{
.maxstack 2 //why is it not 16?
.locals init (
[0] int32 CS$1$0000) //what is this?
L_0000: nop //why this?
L_0001: ldarg.0
L_0002: ldarg.1
L_0003: mul
L_0004: stloc.0 //why this?
L_0005: br.s L_0007 //why this?
L_0007: ldloc.0 //why this?
L_0008: ret
}
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,它还包含一些对我没有意义的额外操作码,实际上我期望以下IL:
.method public …Run Code Online (Sandbox Code Playgroud) 我试图运行出现的文档页面上的示例代码System.Reflection.Emit.LocalBuilder类,但它看来,调用LocalBuilder.SetLocalSymInfo(string, int, int)没有做任何事情,因为IL反汇编显示了这个作为IL的SampleAssembly.dll:
.method public static string Function1(int32 A_0) cil managed
{
// Code size 10 (0xa)
.maxstack 1
.locals init (string V_0,
int32 V_1)
IL_0000: ldarg.0
IL_0001: stloc.1
IL_0002: ldstr "string value"
IL_0007: stloc.0
IL_0008: ldloc.0
IL_0009: ret
} // end of method Example::Function1
Run Code Online (Sandbox Code Playgroud)
为什么不在Dissasembler中列出变量名(myString和myInt)?
环境信息:
编辑:正如我在评论中提到的,有一个SampleAssembly.pdb文件与SampleAssembly.dll文件一起生成.
我需要(忍受我)由于某种原因使用WinRT版本的System.Text.Encoding命名空间.我可以手动添加对程序集的引用,但它仍将使用mscorlib的实现.我显然无法完全删除mscorlib.
如何强制我的项目使用WinRT的System.Text.Encoding.dll而不是mscorlib?
基本上,我需要它来生成这块IL:
call class [System.Text.Encoding]System.Text.Encoding [System.Text.Encoding]System.Text.Encoding::get_UTF8()
Run Code Online (Sandbox Code Playgroud)
而不是这个:
call class [mscorlib]System.Text.Encoding [mscorlib]System.Text.Encoding::get_UTF8()
Run Code Online (Sandbox Code Playgroud) 我一直在使用LINQPad中的一些C#语句来理解发出的中间语言代码.
我首先尝试了以下代码:
var Container = new {Name = "James"};
Console.WriteLine(Container.Name);
Run Code Online (Sandbox Code Playgroud)
并且看到以下六行IL发射:
IL_0001: ldstr "James"
IL_0006: newobj <>f__AnonymousType0<System.String>..ctor
IL_000B: stloc.0
IL_000C: ldloc.0
IL_000D: callvirt <>f__AnonymousType0<System.String>.get_Name
IL_0012: call System.Console.WriteLine
Run Code Online (Sandbox Code Playgroud)
这是我所期望的,并且非常好地演示了匿名类型是如何只读/不可变的,因为没有set_Name属性.
接下来我尝试了这些陈述:
dynamic Container = new System.Dynamic.ExpandoObject();
Container.Name = "James";
Console.WriteLine(Container.Name);
Run Code Online (Sandbox Code Playgroud)
这会导致大量的IL被释放.我不会在这里粘贴它,但你可以在这个pastebin中找到它.
我理解在管理动态类型和ExpandoObject方面存在相当多的开销,但我不明白为什么看起来System.Console.WriteLine在这种情况下调用是通过内部反射来执行的.
IL_0072: ldstr "WriteLine"
....
IL_00BF: ldtoken System.Console
Run Code Online (Sandbox Code Playgroud)
在第一段代码中,在检索并存储属性之后,它是一个调用的单行IL语句System.Console.WriteLine.
那么为什么一个dynamic类型的呼叫需要额外的所有这些?
我有一些我写的自定义IL,它不会通过PEVerify.我得到的错误是
$ peverify foo.exe Microsoft (R) .NET Framework PE Verifier. Version 4.0.30319.17929 Copyright (c) Microsoft Corporation. All rights reserved. [IL]: Error: [Z:\virtualbox_shared\foo.exe : HelloWorld.Program::Main][offset 0x00000021] Stack height at all points must be determinable in a single forward scan of IL. 1 Error(s) Verifying foo.exe
然而,该程序将运行正常,没有任何例外.以下是相关方法的IL:
.method private static hidebysig
default void Main (string[] args) cil managed
{
// Method begins at RVA 0x2050
.entrypoint
// Code size 54 (0x36)
.maxstack 2
//custom IL
ldc.i4 1
ldc.i4 1
ceq
switch(first, second) …Run Code Online (Sandbox Code Playgroud) 我在一个相当大的代码库中工作,今天我找到了IL code一个正常的内部发光项目class.
包含要发出的IL代码的项目是Service Locator MSDN描述的实现.
什么是这样做的优点和为什么会变成这样做是并列使用的C#语言?
因此,今天我使用ILSpy + dotPeek反映了一个使用ILSpy + dotPeek的仲裁.NET程序集,以便在我偶然发现这个奇怪的部分(虚拟示例)时更深入地了解IL代码的工作原理:
public class SomeBaseClass {
public SomeBaseClass(SomeType[] iExpectACollection) {
...
}
}
public class SomeDerivedClass {
public SomeDerivedClass(SomeType onlyOneInstance) {
SomeType[] collection;
if(onlyOneInstance != null)
collection = new SomeType[] { onlyOneInstance };
base.\u002Ector(collection);
}
}
Run Code Online (Sandbox Code Playgroud)
据我所看到的,派生类不调用摆在首位的基础构造,而是做一些事onlyOneInstance,并随后调用是基构造.
我的问题是:在完成一些工作后,是否可以在C#中显式调用基础构造函数?或者这只能在IL中使用?我知道它很容易在Java中使用super(),但是我从未在.NET中看到它.
编辑
我刚和老板谈过,他可以发布一些真实的图书馆代码(这是我们公司的内部代码之一):
**IL PART**
.method public hidebysig specialname rtspecialname
instance void .ctor (
string contextId,
class MyComp.NetStack.BufferManager bufferManager,
class MyComp.NetStack.TcpChannelQuotas quotas,
class [System]System.Security.Cryptography.X509Certificates.X509Certificate2 clientCertificate,
class [System]System.Security.Cryptography.X509Certificates.X509Certificate2[] clientCertificateChain,
class [System]System.Security.Cryptography.X509Certificates.X509Certificate2 serverCertificate,
class MyComp.NetStack.EndpointDescription endpoint, …Run Code Online (Sandbox Code Playgroud) 如何读取值,让我们说:'99'来自包含此代码的程序集?
using Sytem;
public class Class1
{
public Class1() {
// array initializer, want to read '99', '100'... from assembly
var a = new double[,] { { 1, 2, 3 }, { 99, 100, 101 } };
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
ILDASM中的方法:
.method /*06000001*/ public hidebysig specialname rtspecialname
instance void .ctor() cil managed
// SIG: 20 00 01
{
// Method begins at RVA 0x2080
// Code size 29 (0x1d)
.maxstack 3
.locals /*11000001*/ init ([0] float64[0...,0...] …Run Code Online (Sandbox Code Playgroud) il ×10
c# ×7
.net ×5
reflection ×3
cil ×2
.net-4.0 ×1
comments ×1
conflict ×1
dynamic ×1
inheritance ×1
namespaces ×1
opcode ×1
peverify ×1
syntax ×1
vb.net ×1
verification ×1