是否有可能在C#中创建System.Int32?
如果你深入了解C#中的值类型,那么编译器/ CLR会非常特别地处理这些值。 但CLR内部的类型更加特殊。 这是我的意思:
int a = 5;
int b = 10;
int с = a + b;
a.CompareTo(b);
您可以将鼠标悬停在Visual Studio中的int
,然后看到它实际上是System.Int32
结构体。 没关系。 现在,您可以获取ILDasm并查看System.Int32
是什么:返回它是非常简单的结构,它具有一个int32
类型的字段(这是CLR内部的int32
),并且没有重载操作符用于添加。
那么,这个int с = a + b
工作的呢? 我再一次抓住ILDasm并观察IL。 原来在IL代码中没有System.Int32
:编译器会自动理解它应该用int32
代替它。 并且有一个IL指令add
用于堆栈中的int32
对。 CLR允许我在int32
上调用System.Int32
实例方法,这让我更加int32
。 对我来说看起来像是一些黑魔法。
所以,这里是纯粹的理论问题:似乎System.Int32
是类似于任何其他类型的,它可以以某种方式在C#中创建吗? 如果可以,你可以做任何有用的事情(实际的int32
字段是私人的)?
编辑:好的,使它更清楚一点:这个问题没有关于int
是System.Int32
别名。 可以采用提供的示例,用System.Int32
替换int
并跳过示例后面的第一段。 真正的问题是关于在您的IL代码中使用valuetype [mscorlib]System.Int32 a
而不是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);
}
在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
。
从Int32和int中:
将System.Int32作为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的阴影类型。
int32
vs int
(== System.Int32
)
从了解.NET原始类型:
int32是一个CLR原语。 然后在FCL中,它由System.Int32结构体表示。 System.Int32的整数值在其m_value字段中保存,并且在System.Int32上定义了许多与整数相关的方法。
在C#中,int只是System.Int32的别名,由C#编译器支持。 所以int和System.Int32之间没有依赖关系
来自IL“CLR的语言”:
无论使用何种语言开发应用程序,.NET下的所有编译器都会生成中间语言。 事实上,CLR不会意识到用于开发应用程序的语言。 所有的语言编译器都会生成统一的通用语言 - 中间语言。
所以,在C# System.Int32
中就是我们用于IL int32
。 我不知道从C#代码直接与IL一起工作的方式,实际上没有看到任何理由。
有一个:允许在C#/ VB.Net中内联IL的工具
至于int
和System.Int32
:
在SO上的int和System.Int32的帖子:C#,int或Int32? 我应该在乎吗?
在MSDN中:
全部都是一样:
Int32 i = new Int32();
Int32 j = 5;
int x1 = 2;
Int32 x2 = x1;
int
是一个可以说的语法糖......实际上它是System.Int32
除了看看C#语言规范4.1.4简单类型:
C#提供了一组预定义的结构类型,称为简单类型。 简单类型通过保留字标识,但这些保留字只是System名称空间中预定义结构类型的别名,如表中所述
哪里
等等。
CLR有一组基本类型,它们是由CorElementType枚举定义的。 http://msdn.microsoft.com/en-us/library/ms232600.aspx
add,sub,div,rem等操作码对这些类型进行操作。 JIT将把这些变成一些快速汇编代码。 你不能定义新的。 如果你感兴趣,你可以看看它使用SOS生成的代码。
如果你想模仿语言体验,你可以在你的类型中使用运算符重载。 http://msdn.microsoft.com/en-us/library/8edha89s.aspx
链接地址: http://www.djcxy.com/p/11351.html