为啥 .Net 引用类型中有接口?
Posted
技术标签:
【中文标题】为啥 .Net 引用类型中有接口?【英文标题】:Why are interfaces in .Net reference types?为什么 .Net 引用类型中有接口? 【发布时间】:2011-06-06 00:28:00 【问题描述】:为什么接口是引用类型?据我了解,接口是类(或结构)之间的契约,那么为什么它是一种类型呢?我会认为它既不是值类型也不是引用类型。
【问题讨论】:
为什么说接口是引用类型? 嗯,我刚刚参加了 70-536 的练习考试,它说接口是引用类型之一(以及类和委托)。 @nader 它是引用类型... @Mar ... 是的,我真的没有想清楚。我在想一个接口实际上什么都不是。但是实现接口的东西必须被视为引用类型...... 【参考方案1】:要被视为结构,编译器必须在编译时知道具体类型是什么,以便在堆栈上保留正确的空间。这意味着即使一个结构实现了IFoo
,那么使用:
var ms = new MyStruct();
IFoo foo = ms;
那么对foo
的赋值是一个装箱操作。你可以说“编译器应该发现它只是一个 foo 并使用 'constained' 操作码”,但是在一般情况下(对foo
等进行多次分配)这不是可能(我会冒险猜测它会遇到“停止问题”)。
还有一个虚拟与静态调用的问题,但“受约束”的操作码可以解决这个问题。
基本上,接口的任何使用都必须始终被视为参考。
对此有一个例外:通用约束。
如果你有
static void DoBar<T>(T target) where T : IFoo
target.Bar();
这里的方法对每个值类型进行一次 JIT 处理,因此T
所需的堆栈空间是已知的;对Bar
的调用是“受约束的”,可以根据需要自动为虚拟或静态。
【讨论】:
好的,我明白了。所以 MyStruct 实现了 foo,它仍然是一个值类型。但是一旦你将 MyStruct 转换为 foo,它就会被装箱。 foo 的行为使其成为引用类型。此外, foo 可以被分配一个值类型,然后是一个引用类型,它永远不知道,所以它必须表现为一个引用类型来涵盖所有场景......这一切都正确吗?【参考方案2】:它们是引用类型,因为值类型在编译时具有固定大小,因此可以在堆栈上分配它们。引用类型是指针,所以指针是固定大小的,但它们可以指向任意大小的内存。
【讨论】:
以上是关于为啥 .Net 引用类型中有接口?的主要内容,如果未能解决你的问题,请参考以下文章