pho*_*oog 10 .net c# interface value-type reference-type
接口变量是否具有值类型或引用类型语义?
接口按类型实现,这些类型是值类型或引用类型.显然,这两个int和string实现IComparable,并且int是一个值类型,并string为引用类型.但是这个怎么样:
IComparable x = 42;
IComparable y = "Hello, World!";
Run Code Online (Sandbox Code Playgroud)
(我试图回答的问题可能被删除了,因为它询问接口是存储在堆栈还是堆中,而且,正如我们都应该知道的那样,考虑到它们之间的值和引用类型之间的差异更具建设性.语义而不是它们的实现.有关讨论,请参阅Eric Lippert的堆栈是一个实现细节.)
Mar*_*ell 14
通常,根据现有的答案,它是一个参考类型,需要拳击; 但有一个例外(总是不存在吗?).在一个泛型方法where约束,也可以是两个:
void Foo<T>(T obj) where T : ISomeInterface {
obj.SomeMethod();
}
Run Code Online (Sandbox Code Playgroud)
这是一个受约束的操作,即使它是值类型也不会装箱.这是通过constrained.相反,JIT执行操作作为引用类型的虚拟调用,以及对值类型的静态调用.没拳击.
类型为 的变量或字段IComparable是引用类型变量或字段,无论分配给该字段的值的类型如何。这意味着x示例代码中是装箱的。
一个简单的测试就可以证明这一点。该测试基于以下事实:您只能将值类型拆箱为其原始类型(以及该类型的可为空版本):
[TestMethod, ExpectedException(typeof(InvalidCastException))]
public void BoxingTest()
{
IComparable i = 42;
byte b = (byte)i; //exception: not allowed to unbox an int to any type other than int
Assert.AreEqual(42, b);
Assert.Fail();
}
Run Code Online (Sandbox Code Playgroud)
编辑
除此之外,C# 规范还专门将引用类型定义为包含类类型、接口类型、数组类型和委托类型。
编辑2
正如 Marc Gravell 在他的回答中指出的那样,具有接口约束的泛型类型是一种不同的情况。这不会引起拳击。
这是关于理解类型的装箱和拆箱.在您的示例中,int在赋值时被加框,并且对该"box"或对象的引用是分配给x的内容.值类型int被定义为实现IComparable的结构.但是,一旦使用该接口引用引用值类型int,它将被装箱并放在堆上.这就是它在实践中的运作方式.使用接口引用导致装箱按定义发生的事实使得此引用类型语义.
| 归档时间: |
|
| 查看次数: |
7652 次 |
| 最近记录: |