您可以在IL中的.NET中的接口上定义静态构造函数.但是,如果这样做,则在接口上运行方法时不会运行静态构造函数:
.method public static void Main() {
.entrypoint
.locals init ( class IInterface cls1 )
// InterfaceClass static constructor is run
newobj instance void InterfaceClass::.ctor()
stloc.0
ldloc.0
// IInterface static constructor is not run!!!!!
callvirt instance int32 IInterface::Method()
call void [mscorlib]System.Console::WriteLine(int32)
ret
}
.class public interface IInterface {
.method private static specialname rtspecialname void .cctor() {
ldstr "Interface static cctor"
call void [mscorlib]System.Console::WriteLine(string)
ret
}
.method public abstract virtual instance int32 Method() {}
}
.class public InterfaceClass implements IInterface { …Run Code Online (Sandbox Code Playgroud) 在C#6之前,属性的初始化不使用支持字段来初始化默认值.在C#6中,它使用支持字段来初始化新的自动初始化属性.
我很好奇为什么在C#6 IL之前使用属性定义进行初始化.这有什么特别的原因吗?或者在C#6之前没有正确实施?
在C#6.0之前
public class PropertyInitialization
{
public string First { get; set; }
public string Last { get; set; }
public PropertyInitialization()
{
this.First = "Adam";
this.Last = "Smith";
}
}
Run Code Online (Sandbox Code Playgroud)
编译器生成代码(IL表示)
public class PropertyInitialisation
{
[CompilerGenerated]
private string \u003CFirst\u003Ek__BackingField;
[CompilerGenerated]
private string \u003CLast\u003Ek__BackingField;
public string First
{
get
{
return this.\u003CFirst\u003Ek__BackingField;
}
set
{
this.\u003CFirst\u003Ek__BackingField = value;
}
}
public string Last
{
get
{
return this.\u003CLast\u003Ek__BackingField;
}
set
{
this.\u003CLast\u003Ek__BackingField = value;
}
} …Run Code Online (Sandbox Code Playgroud) 我想在运行时向某个类添加一些行为.我知道如何在运行时使用Reflection.Emit进行子类化,但这还不够,根据一些外部配置,我需要在类型T上的方法中注入操作码,以便从中继承的所有类自动获得此行为.(我无法使用.NET分析API)
可以用Mono.Cecil完成这样的事吗?
如果不能修改加载的程序集上的代码,那很好.如果我可以在加载程序集之前进行修改然后将修改后的程序集加载到内存中,但我不知道如何控制程序集加载.
假设您在C#,VB中编写应用程序,使用.NET编写任何内容当您点击构建时,它是否真的编译了您的代码?我一直这么想,直到我开始在我的一些装配上使用redgates反射器并逐字地看到我的代码.我本来期望循环展开和另外多次优化,而不是什么.
那么编译什么时候实际发生?我认为当它构建时,代码变成IL(中介语言),并且当执行时,它正在加载到CLR中?它是仅在CLR期间优化而从未在构建时进行优化的吗?
目前我正在为大学做一个关于F#的培训.我有一个关于F#交互式控制台和F#编译器的问题.
F#编译器在编译F#-source时生成Microsoft中间语言(MSIL)代码.然后,在执行编写的程序时,JIT编译器将其转换为机器代码.
但是F#Interpreter Console有什么作用?它是否也按行每行将F#代码转换为MSIL,然后将其转换为机器代码?或者它是否将F#-Code直接转换为机器代码?
如果它首先将它转换为IL,那么我认为可能会有一个IL解释器,因为JIT编译器只编译完整的程序.不是吗?
你怎么看,F#-interpreter如何处理F#代码并进行翻译?
问候,马丁
我发现了IL code一个简单的程序:
long x = 0;
for(long i = 0;i< int.MaxValue * 2L; i++)
{
x = i;
}
Console.WriteLine(x);
Run Code Online (Sandbox Code Playgroud)
我在发布模式下构建此代码并IL code生成:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 28 (0x1c)
.maxstack 2
.locals init ([0] int64 x,
[1] int64 i)
IL_0000: ldc.i4.0
IL_0001: conv.i8
IL_0002: stloc.0
IL_0003: ldc.i4.0
IL_0004: conv.i8
IL_0005: stloc.1
IL_0006: br.s IL_000f
IL_0008: ldloc.1
IL_0009: stloc.0
IL_000a: ldloc.1
IL_000b: ldc.i4.1
IL_000c: conv.i8
IL_000d: …Run Code Online (Sandbox Code Playgroud) 这可能是一个愚蠢的问题,但是有没有IL代码的编译器,类似于IL模式下Reflector所示的?
我有兴趣学习汇编,特别是因为我发现多态代码相当有趣,我对于我应该学习的东西感到困惑.
我听说x86是最常见的学习或开始,但不是大多数应用程序(用Visual Studio编写)使用不同的汇编语言?或者在普通中级语言中还是什么?或者CIL或IL或其他什么在运行时被编译到x86中?
compiler-construction x86 assembly intermediate-language visual-studio
在进行向上或向下投射时,幕后真的会发生什么?我有一个想法,当做某事时:
string myString = "abc";
object myObject = myString;
string myStringBack = (string)myObject;
Run Code Online (Sandbox Code Playgroud)
最后一行中的强制转换只有目的告诉编译器我们是安全的,我们没有做错任何事.所以,我认为实际上代码本身不会嵌入任何强制转换代码.看来我错了:
.maxstack 1
.locals init (
[0] string myString,
[1] object myObject,
[2] string myStringBack)
L_0000: nop
L_0001: ldstr "abc"
L_0006: stloc.0
L_0007: ldloc.0
L_0008: stloc.1
L_0009: ldloc.1
L_000a: castclass string
L_000f: stloc.2
L_0010: ret
Run Code Online (Sandbox Code Playgroud)
为什么CLR需要类似的东西castclass string?
向下转换有两种可能的实现方式:
castclass something.当你到达执行的代码行时castclass,CLR会尝试进行强制转换.但是,如果我省略了castclass字符串行并尝试运行代码,会发生什么?castclass.由于所有引用类型都具有类似的内部结构,如果您尝试在Form实例上使用字符串,它将抛出错误用法的异常(因为它检测到Form不是字符串或其任何子类型).另外,来自C#4.0的以下statamente在Nutshell中是否正确?
Upcasting and downcasting between compatible reference types performs reference
conversions: a new reference is created that points …Run Code Online (Sandbox Code Playgroud) 我正在看这个,它的起始评论说它存在,因为
throw new ArgumentNullException("key", Environment.GetResourceString("ArgumentNull_Key"));
Run Code Online (Sandbox Code Playgroud)
生成的 IL 代码多于
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key, ExceptionResource.ArgumentNull_Key);
Run Code Online (Sandbox Code Playgroud)
我在代码中找不到它,但就像它的类似方法一样,我假设只是调用throw new ArgumentNullException("key", Environment.GetResourceString("ArgumentNull_Key"));或其他东西。
ThrowHelper 类是否真的有助于减少生成的 IL 代码,或者考虑到从 生成的 IL 代码,它是否相同(或更多)ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key, ExceptionResource.ArgumentNull_Key);?
编辑:文件开头的注释中显示的 IL 仅来自对该ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key, ExceptionResource.ArgumentNull_Key);方法内的实际代码的调用。还是我错了?