本篇所写都是本人想当然的理解。如果这种理解便于帮助你理解一些知识的话,我会感到由衷的欣慰。
   .net中虽然没有指针语法,但是在堆中分配对象,将引用放在栈中,十分类似C++中的指针操作,此时引用就可以看成一种特殊的指针。因为指针操作的间接性,会带来一定的性能影响,为了避免这种影响,.net采取了一种折衷的办法,引入了值类型。

   为了在值类型和引用类型之间进行一些合理的转换,于是带来了装箱和拆箱。
   装箱简单来说就是将值类型转换为引用类型。按三步进行:
(1)新分配托管堆内存(大小为值类型实例大小加上一个方法表指针和一个SyncBlockIndex)。
(2)将值类型的实例字段拷贝到新分配的内存中。
(3)返回托管堆中新分配对象的地址。

    拆箱就是将引用类型转换为对应的值类型。分如下步骤进行:
(1)检查引用对象实例,确保它是给定值类型的一个装箱值。
(2)获取引用对象中指向值类型部分的指针。
(3)将引用对象中对应的内容拷贝到值类型区域。

从上面步骤可以看出,装箱和拆箱会给程序的性能带来一定的影响,所以我们应尽可能地避免装箱和拆箱。装箱可以隐式进行,拆箱只能显式进行。只有先装箱,才能拆箱。

为了尽可能地避免装箱和拆箱,我们需要了解装箱的几种情况。
我总结了以下几种(可能不太全面):
(1)方法中参数为Object类,但是传递一个值类型。

1.net中装箱的几种情况void f(object obj)
2}


(2)一个类型中有field申明为Object类,赋予一个值类型。

 1.net中装箱的几种情况class Container
 2    }


(3)调用Object类中没有被值类型覆盖的方法,如GetType()。

 1.net中装箱的几种情况 
 2.net中装箱的几种情况  //值类型,这里借用《.net框架程序设计》中的例子,并做了适当修改
 3.net中装箱的几种情况    struct MyValType
 4    }


(4)将值类型转换为成一个被该值类型实现的接口类型。

 1.net中装箱的几种情况interface IChange
 2    }

针对以上四种情况,为了减少装箱和拆箱,建议以如下形式进行:
(1)方法中参数为Object类,但是传递一个值类型。               建议利用方法重载或者泛型。
(2)一个类型中有field申明为Object类,赋予一个值类型。   建议利用泛型。

(3)调用Object类中没有被值类型覆盖的方法,如GetType()。
根据实际情况,判断是否有其它方法实现,如上面举的例子就可以这样修改:

 1.net中装箱的几种情况//值类型
 2.net中装箱的几种情况    struct MyValType
 3    }


(4)将值类型转换为成一个被该值类型实现的接口类型。如果设计上真要求这么做,那可能只能如此了。我暂时没有想到什么解法,如果你有更好的解法,希望不吝赐教。

相关文章:

  • 2022-01-24
  • 2021-11-29
  • 2022-02-24
  • 2022-03-09
  • 2021-07-05
  • 2021-08-18
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2021-08-13
  • 2022-12-23
  • 2021-06-30
  • 2021-10-23
  • 2021-08-14
  • 2021-05-06
相关资源
相似解决方案