百科问答小站 logo
百科问答小站 font logo



object是引用类型吗? 第1页

  

user avatar   Ivony 网友的相关建议: 
      

object是只读对象,引用类型。

我真心觉得初学者完全没必要搞清楚引用类型和值类型的区别,毕竟堆栈是啥都没弄明白前,不清楚声明类型和运行时类型什么区别前,怎么去理解引用类型和值类型的区别在于编译后的运行时行为。


混淆只读对象和值类型是最容易犯的错误之一。只读对象根本没有办法通过改变状态来观察到引用类型的行为,事实上用对象改变同一引用的另一对象改变来定义引用类型也是错误的,引用类型和值类型的定义是运行时行为(而这关系到了使用引用类型还是值类型的决策)。搞不懂就背书,从ValueType继承的除去Enum都是值类型,其余的都不是。

因为很多面试官喜欢考这个,所以背背就好了。


好吧我就多罗嗦几句吧,要真正理解透彻引用类型和值类型必须要到CLR的行为层面。这里只简单的说说什么是只读对象,以及怎么用代码去验证引用类型。

只读对象就是指没有办法修改其状态的对象(也就是说没有字段,或者没有公开的修改字段的方法或属性以及事件)。

例如new object(),这就是一个只读对象,"abc"也是只读对象。

用修改对象的状态来观察是引用类型还是值类型这一方法对于只读对象是无效的,因为只读对象的状态没有办法被修改。

正确的修改对象状态来观察引用类型的方式是这样的:

       int[] array = new int[]{ 1, 2, 3 }; var array1 = array; Console.WriteLine( string.Join( ",", array1 ) ); array[0] = 5; Console.WriteLine( string.Join( ",", array1 ) );      

int[],即数组类型,是一个典型的引用类型,其状态,即数组元素是可以修改的。所以通过修改数组元素,我们就能观察到引用类型的特性。


而值类型,绝大多数值类型都被设计为只读对象,这其实是值类型的设计原则之一。除非我们构建一个不符合设计原则的值类型,否则我们观察不到赋值的时候值类型被复制的行为。

这也是我比较反感用状态变化来说明引用类型和值类型以及非要给初学者强调引用类型和值类型区别的原因。我给初学者的建议就是没事别自己弄个struct,除非你已经完全明白你在干吗


那么不自定义值类型,能不能观察到值类型与引用类型的行为不同呢?

可以。

       {   var obj1 = new object();   var obj2 = obj1;    Console.WriteLine( object.ReferenceEquals( obj1, obj2 ) ); }   {   var obj1 = new int();   var obj2 = obj1;    Console.WriteLine( object.ReferenceEquals( obj1, obj2 ) ); }      

这是比较好的判断值类型和引用类型的方法,不过原理却不是因为值类型在赋值的时候被复制了,而是因为在ReferenceEquals的时候会被装箱(装箱就是运行时行为的一个不同,只有值类型会导致装箱,引用类型不会导致装箱)。

大家不妨猜一下下面这段代码结果是什么:

       {   var obj1 = new int();    Console.WriteLine( object.ReferenceEquals( obj1, obj1 ) ); }      



  

相关话题

  微软当年的 J++ 究竟是什么?为什么 Sun 要告它? 
  C# 异步中Task.Wait的坑? C# Task.Wait为什么不等待就返回? 
  为什么微软不把C# 设计成像C++一样可以编写底层3D程序的一门语言了? 
  在C++中,“?:”这个符号叫什么名字? 
  C语言的设计模式有哪些? 
  为什么几乎所有的量化交易都用Python? 
  如何修改开源应用程序的功能? 
  c#中虽然异步和多线程是两码事,但是是否异步微软提供的async函数内部还是多线程去实现的? 
  真的会有人用 vim 开发大的项目吗? 
  如何评价 ASP.NET vNext? 

前一个讨论
父亲对女儿产生性幻想正常么?
下一个讨论
转基因食物的基因是否可在人体内表达出有毒蛋白?





© 2024-11-22 - tinynew.org. All Rights Reserved.
© 2024-11-22 - tinynew.org. 保留所有权利