是否可以在C#中创建System.Int32? [英] Is it possible to create System.Int32 in C#?
问题描述
如果深入了解,编译器/CLR将非常特殊地对待C#中的值类型.但是CLR内部的类型甚至被更特别地对待.这是我的意思:
If you get under the hood, value types in C# are treated very specially by compiler/CLR. But types internal to CLR are treated even more specially. Here is what I mean:
int a = 5;
int b = 10;
int с = a + b;
a.CompareTo(b);
您可以将鼠标悬停在Visual Studio中的 int
上,并查看它实际上是 System.Int32
结构.没关系.现在,您可以获取ILDasm,并查看什么是 System.Int32
:翻过来这是一个非常简单的结构,具有一个类型为 int32
的字段(这是 int32
CLR内部),并且没有用于添加的重载运算符.
You can hover with your mouse over int
in Visual Studio and see that actually it is System.Int32
struct. That's OK. Now you can grab ILDasm and look into what System.Int32
is: turns over that it is very simple struct with one field of type int32
(this is int32
internal to CLR) and there is no overloaded operator for addition.
那么,这个 intс= a + b
的工作原理是什么?我再次抓住ILDasm并调查IL.事实证明,IL代码中没有 System.Int32
:编译器自动了解它应将其替换为 int32
.IL指令 add
适用于堆栈上的几个 int32
上调用 System.Int32
的实例方法.对我来说似乎是一些黑魔法.
So, how this int с = a + b
works then? Again I grab ILDasm and look into IL. Turns out that there is no System.Int32
in IL code: compiler automatically understands that it should replace it with int32
. And there is IL instruction add
that works for couple of int32
on a stack. What amuses me even more, CLR allows to call instance methods for System.Int32
on int32
. Looks like some black magic to me.
因此,这里有一个纯理论上的问题:似乎 System.Int32
的类型与其他类型相同,是否可以用C#创建它?如果可以的话,您能做些有用的事吗(实际的 int32
字段是私有的)?
So, here goes the pure theoretical question: seems that System.Int32
is type like any other, could it be created in C# somehow? And if it could, could you do anything useful with it (actual int32
field is private)?
好吧,让它更清楚一点:这个问题与 int
是 System.Int32
的别名无关.可以以提供的示例为例,将 int
替换为 System.Int32
,然后跳过该示例之后的第一段.真正的问题是,在您的IL代码中可能具有 valuetype [mscorlib] System.Int32 a
的可能性,而不仅仅是 int32 a
.
Ok, to make it a bit more clear: this question have nothing about int
being alias to System.Int32
. One can take provided example, replace int
with System.Int32
and skip first paragraph after the example. The real question is about possibility to have valuetype [mscorlib]System.Int32 a
in your IL code instead of just int32 a
.
推荐答案
因此,请考虑以下代码:
So, consider the following code:
static void Main(string[] args)
{
int x = 5;
Print(x);
Console.ReadLine();
}
static void Print(object x)
{
int y = (int)x;
Console.WriteLine(y);
}
在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
[mscorlib] System.Int32
仅用于装箱/拆箱.当变量在堆栈中时,它总是 int32
.
[mscorlib]System.Int32
is used for boxing/unboxing only. When the variable is in stack, it's always int32
.
来自 Int32和int :
将System.Int32视为int32的影子类型可能会有所帮助.
It might be helpful to think of System.Int32 as a shadow type for int32.
以下C#代码:
int x = 0;
x.ToString();
在IL中是这个吗?
ldc.i4.0
stloc.0
ldloca.s 0
call instance class System.String [mscorlib]System.Int32::ToString()
pop
请注意如何将int32传递给看似不兼容的System.Int32结构.引擎允许这种原因,已被硬连线识别System.Int32作为int32的影子类型.
Notice how it's passing an int32 into a seemingly incompatible System.Int32 struct. The engine allows this cause it has been hardwired to recognise System.Int32 as the shadow type of int32.
这篇关于是否可以在C#中创建System.Int32?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!