[英]C# supports value types and reference types, but are they all objects?
我知道C#有值和引用类型,但是你怎么能这样做:
int age = 100;
string blah = age.ToString();
如果age是一个值类型,它有一个ToString方法吗? 它是否仅在内部需要时才转换为对象?
如果age是一个值类型,它有一个ToString方法吗?
允许值类型具有方法。 他们为什么不呢? “在类型上”的方法只是恰好与特定类型相关联的一大块代码 ; 为什么你认为这种类型被归类为“参考类型”还是“价值类型”?
这不是一个修辞问题。 我有兴趣了解人们对代码的直觉,特别是当这些直觉不正确时。 通过直观地理解人们弄错了什么,我们可以尝试提出更直观的更好的抽象。
它是否仅在内部需要时才转换为对象?
“转换为对象”究竟是什么意思? 你的意思是“盒装”?
在许多情况下,必须将值类型装箱。 其中一些很简单 - 就像将值类型转换为对象或接口时一样。 其中一些是模糊的。 (在通用方法中有一些奇怪的情况,我们必须以你可能没想到的方式装箱和拆箱。)
在这种特殊情况下,没有拳击。 调用直接在值类型上实现的方法只调用那段代码。 没有必要将这个东西视为“对象”; 我们调用的代码块知道事物的类型。
System.Int32
继承继承System.Object
System.ValueType
。
所有类,结构,枚举,数组,可空和委托类型最终都是从对象派生的。 所有接口类型和类型参数类型都可以隐式转换为对象。 并且所有指针类型既不源自也不可转换为对象
你想查找装箱/拆箱。
所有Framework对象都继承自System.Object(尽管可以在MSIL中声明一个不具有的类型)。
object.ToString()
方法是一个虚方法。
尝试从System.Object
调用方法的值类型的特殊规则是:
如果值类型已重写方法(因为int和所有数字类型都使用ToString()
),则值类型不会被装箱(“转换”或“包装”到对象),但直接调用实现方法。
如果值类型未提供此类方法的实现(例如,自定义struct
),则将值类型装箱,并调用基本实现的mathod。
至于装箱/拆箱的细节,msdn中有很多信息。
所有类型(引用和值)都继承自Object。 (虽然像其他人一样说可以定义一个没有,但不能在C#中,你必须在MSIL中这样做)
这意味着任何值类型仍将继承基础对象的方法。 为了使值类型在基础对象类型上调用方法,必须首先对其进行装箱,以便将其视为引用类型(装箱是获取值类型并将其推入引用类型形状框的过程,因此它表现得像参考类型)。 但是在这个特定的情况下,Int32实现了它自己的ToString版本(和大多数常见的数值类型一样),这只是值类型本身的常规方法,因此不必将其装箱来调用它。
值类型可以像引用类型一样具有方法和属性。 限制是结构(C#的值类型)不支持继承(除了Object)或终结器。
还有价值和引用类型之间的区别的好文章在这里 。
比较“值类型”与“引用类型”并未说明类型是否为对象。 所有它告诉你的是你是类型的语义:比如它如何传递给函数,是否需要使用'new'来实例化它,以及它是存储在堆栈还是堆上。 即便是最后一个也只是一个实现细节 。
也许需要更多地了解OO调用约定。
创建对象时,它实际上不会复制ToString的代码,而是在后台转换对象调用
target.ToString();
到逻辑上的东西:
ToString(目标);
因此,只有一个函数代码副本(每个多态实例),并且在调用方法时传入对象指针。
所有的答案大多是正确的,但我觉得这个方法属于system.object和system.valuetype,system.Int32是从它派生的。所以当你创建它的权限时,它将显示基类的方法。
盒装值类型继承自object,但它们具有引用语义而不是值语义。 未装箱的值类型不是对象,但在值类型和对象之间存在隐式表示更改转换。 and Object. 接口类型不从Object继承,但在和Object的之间存在隐式表示保留转换。 请注意,泛型上的接口约束不会使泛型类型成为接口类型。 如果泛型类型恰好是值类型,则从泛型类型到Object或接口类型的转换将是表示保留转换,即使它实现了转换其类型的接口。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.