如果你深入了解,C#中的值类型将由编译器/ CLR特别处理。但是CLR内部的类型更加特殊。这就是我的意思:
int a = 5;
int b = 10;
int с = a + b;
a.CompareTo(b);
您可以将鼠标悬停在Visual Studio中的int
上,看看它实际上是System.Int32
struct。没关系。现在你可以获取ILDasm并查看System.Int32
是什么:转换它是一个非常简单的struct,其中一个类型为int32
的字段(这是CLR内部的int32
)并且没有重载运算符。
那么,int с = a + b
如何运作呢?我再次抓住ILDasm并研究IL。事实证明IL代码中没有System.Int32
:编译器自动理解它应该用int32
替换它。 IL指令add
适用于堆栈上的int32
个。更让我感到有趣的是,CLR允许在System.Int32
上调用int32
的实例方法。看起来像是一些黑魔法。
所以,这里是纯粹的理论问题:似乎System.Int32
的类型与其他类似,是否可以用C#创建?如果可以的话,你能用它做一些有用的事情(实际的int32
字段是私有的吗?)
修改:好了,为了更清楚一点:这个问题与int
System.Int32
的别名无关。可以采用提供的示例,将int
替换为System.Int32
,并在示例后跳过第一段。真正的问题是有可能在您的IL代码中使用valuetype [mscorlib]System.Int32 a
而不仅仅是int32 a
。
答案 0 :(得分:2)
因此,请考虑以下代码:
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
。
将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的影子类型。
答案 1 :(得分:1)
int32
vs int
(== System.Int32
)
来自Understanding .NET Primitive Types :
int32是一个CLR原语。然后在FCL中,它表示为 System.Int32结构。 System.Int32的整数值保持不变 它的m_value已归档,并且定义了许多与整数相关的方法 System.Int32。
在C#中,int只是System.Int32的别名,由C#支持 编译器。因此int和System.Int32
之间没有依赖关系
.NET下的所有编译器都会生成中间语言 用什么语言来开发应用程序。事实上,CLR不会 了解用于开发应用程序的语言。所有语言 编译器将生成一种统一的通用语言Intermediate 语言。
因此,在C#System.Int32
中我们对IL int32
有所了解。我不知道直接使用C#代码处理IL的方法,实际上看不出任何理由。
有一个:Tool to allow inline IL in C# / VB.Net
至于int
vs System.Int32
:
关于SO的帖子和SO上的System.Int32:C#, int or Int32? Should I care?
在MSDN中:
一切都是一样的:
Int32 i = new Int32();
Int32 j = 5;
int x1 = 2;
Int32 x2 = x1;
int
可以说语法糖 ......实际上它是System.Int32
除了看看C#语言规范4.1.4简单类型:
C#提供了一组称为简单类型的预定义结构类型。 简单类型通过保留字识别,但这些 保留字只是预定义结构类型的别名 系统名称空间,如表
中所述
,其中
等等。
答案 2 :(得分:0)
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