如果你深入了解C#中的值类型,那么编译器/ CLR会非常特别地对待它们.但是CLR内部的类型更加特殊.这就是我的意思:
int a = 5;
int b = 10;
int ? = a + b;
a.CompareTo(b);
Run Code Online (Sandbox Code Playgroud)
您可以将鼠标悬停int在Visual Studio中,看看它实际上是System.Int32struct.没关系.现在你可以抓住ILDasm并查看是什么System.Int32:转换它是一个非常简单的struct,有一个类型的字段int32(这是int32CLR的内部),并且没有重载的运算符用于添加.
那么,这int ? = a + b是如何工作的呢?我再次抓住ILDasm并研究IL.事实证明System.Int32IL代码中没有:编译器自动理解它应该替换它int32.并且IL指令add适用于int32堆栈中的几个.是什么使我感到有趣甚至更多,CLR允许呼叫实例方法System.Int32上int32.看起来像是一些黑魔法给我.
所以,这里是纯粹的理论问题:看起来System.Int32像任何其他的类型,它可以用C#以某种方式创建吗?如果可以,你可以用它做任何有用的事情(实际int32领域是私人的)吗?
编辑:好的,为了使它更清楚:这个问题没有关于int别名的问题System.Int32.一个可以提供例如,更换int与System.Int32和跳过例子后第一段.真正的问题是关于valuetype [mscorlib]System.Int32 a你的IL代码而不仅仅是的可能性int32 a.
因此,请考虑以下代码:
static void Main(string[] args)
{
int x = 5;
Print(x);
Console.ReadLine();
}
static void Print(object x)
{
int y = (int)x;
Console.WriteLine(y);
}
Run Code Online (Sandbox Code Playgroud)
在ILDasm中:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
.maxstack 1
.locals init ([0] int32 x)
IL_0000: nop
IL_0001: ldc.i4.5
IL_0002: stloc.0
IL_0003: ldloc.0
IL_0004: box [mscorlib]System.Int32
IL_0009: call void Test.Program::Print(object)
IL_000e: nop
IL_000f: call string [mscorlib]System.Console::ReadLine()
IL_0014: pop
IL_0015: ret
} // end of method Program::Main
.method private hidebysig static void Print(object x) cil managed
{
.maxstack 1
.locals init ([0] int32 y)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: unbox.any [mscorlib]System.Int32
IL_0007: stloc.0
IL_0008: ldloc.0
IL_0009: call void [mscorlib]System.Console::WriteLine(int32)
IL_000e: nop
IL_000f: ret
} // end of method Program::Print
Run Code Online (Sandbox Code Playgroud)
[mscorlib]System.Int32仅用于装箱/拆箱。当变量在堆栈中时,它始终是int32。
将 System.Int32 视为 int32 的影子类型可能会有所帮助。
以下 C# 代码:
int x = 0;
x.ToString();
Run Code Online (Sandbox Code Playgroud)
这是在伊利诺伊州吗:
ldc.i4.0
stloc.0
ldloca.s 0
call instance class System.String [mscorlib]System.Int32::ToString()
pop
Run Code Online (Sandbox Code Playgroud)
请注意它如何将 int32 传递到看似不兼容的 System.Int32 结构中。引擎允许这样做,因为它已硬连线将 System.Int32 识别为 int32 的影子类型。
| 归档时间: |
|
| 查看次数: |
1440 次 |
| 最近记录: |