是否有可能在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字段是私人的)?

编辑:好的,使它更清楚一点:这个问题没有关于intSystem.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的工具


至于intSystem.Int32

在SO上的int和System.Int32的帖子:C#,int或Int32? 我应该在乎吗?

在MSDN中:

  • Int32结构
  • int(C#参考)
  • 全部都是一样:

    Int32 i = new Int32();
    Int32 j = 5;
    int x1 = 2;
    Int32 x2 = x1;
    

    int是一个可以说的语法糖......实际上它是System.Int32

    除了看看C#语言规范4.1.4简单类型:

    C#提供了一组预定义的结构类型,称为简单类型。 简单类型通过保留字标识,但这些保留字只是System名称空间中预定义结构类型的别名,如表中所述

    哪里

  • short => System.Int16
  • int => System.Int32
  • 长=> System.Int64
  • 等等。


    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

    上一篇: Is it possible to create System.Int32 in C#?

    下一篇: How to avoid broken dashed lines in GDI+?