【CLR Via C#笔记】操作符重载

本文详细介绍了C#中Decimal类型的内部实现,包括操作符重载和类型转换的过程,并通过IL代码示例展示了这些操作的实际执行方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

System.Decimal 类型是个特殊的类型,他并不直接属于CLR IL的基本类型,而是C#语言自己定义的。(其他值类型比如System.Int32都有对应的IL类型int32)

因此可以通过Reflector查看关于操作符重载和转换操作符的方法

1. 操作符重载

ContractedBlock.gifExpandedBlockStart.gifCode
//正:+decimal1
        public static decimal operator +(decimal d)
        {
            
return d;
        }
//负:-decimal1
        public static decimal operator -(decimal d)
        {
            
return Negate(d);
        }
//自增:decimal1++
        public static decimal operator ++(decimal d)
        {
            
return Add(d, 1M);
        }
//自减:decimal1--
        public static decimal operator --(decimal d)
        {
            
return Subtract(d, 1M);
        }
//加法 decimal1 + decimal2
        public static decimal operator +(decimal d1, decimal d2)
        {
            
return Add(d1, d2);
        }

 

2. 转化操作符

ContractedBlock.gifExpandedBlockStart.gifCode
//隐式转化: int i =2; decimal d1 = i;
        public static implicit operator decimal(int value)
        {
            
return new decimal(value);
        }
//显示转化:decimal d1 = 2.32; short s1 = (short)d1;
        public static explicit operator short(decimal value)
        {
            
return ToInt16(value);
        }

 

3. 实际上,上述操作符重载方法最终将编译成普通IL方法。

c#编译器在源码中看到一个+号时,会去查看是否定义了一个op_Addition的方法(对应+操作符)并检查参数类型是否兼容。

而对于隐式转化,将分别编译成op_Implicit的不同重载方法(overload)

显式转化编译成op_Explicit的不同重载方法,而且是C#不支持但CLR支持的同名同参数不同返回值类型方法。

 

ContractedBlock.gifExpandedBlockStart.gifCode
//ILDASM 查看decimal的加号重载
.method public hidebysig specialname static 
        valuetype System.Decimal  op_Addition(valuetype System.Decimal d1,
                                              valuetype System.Decimal d2) cil managed
{
  
// 代码大小       8 (0x8)
  .maxstack  8
  IL_0000:  ldarg.
0
  IL_0001:  ldarg.
1
  IL_0002:  call       valuetype System.Decimal System.Decimal::Add(valuetype System.Decimal,
                                                                    valuetype System.Decimal)
  IL_0007:  ret
// end of method Decimal::op_Addition


//从Int64隐式转化为decimal方法的IL代码
.method public hidebysig specialname static 
        valuetype System.Decimal  op_Implicit(int64 
'value') cil managed
{
  
// 代码大小       7 (0x7)
  .maxstack  8
  IL_0000:  ldarg.
0
  IL_0001:  newobj     instance 
void System.Decimal::.ctor(int64)
  IL_0006:  ret
// end of method Decimal::op_Implicit

//从char隐式转化为decimal方法的IL代码
.method public hidebysig specialname static 
        valuetype System.Decimal  op_Implicit(
char 'value') cil managed
{
  
// 代码大小       7 (0x7)
  .maxstack  8
  IL_0000:  ldarg.
0
  IL_0001:  newobj     instance 
void System.Decimal::.ctor(int32)
  IL_0006:  ret
// end of method Decimal::op_Implicit


//显式转化为Double型方法的IL代码 注意返回类型是float64即C#中double
.method public hidebysig specialname static 
        float64  op_Explicit(valuetype System.Decimal 
'value') cil managed
{
  
// 代码大小       7 (0x7)
  .maxstack  8
  IL_0000:  ldarg.
0
  IL_0001:  call       float64 System.Decimal::ToDouble(valuetype System.Decimal)
  IL_0006:  ret
// end of method Decimal::op_Explicit


//显式转化为Int32.与上面相比函数定义只有返回类型不同
.method public hidebysig specialname static 
        int32  op_Explicit(valuetype System.Decimal 
'value') cil managed
{
  
// 代码大小       7 (0x7)
  .maxstack  8
  IL_0000:  ldarg.
0
  IL_0001:  call       int32 System.Decimal::ToInt32(valuetype System.Decimal)
  IL_0006:  ret
// end of method Decimal::op_Explicit

 

 

转载于:https://www.cnblogs.com/calmzeal/archive/2008/11/11/1331489.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值