c# - 有关结构实现接口(interface)时发生的情况的详细信息

标签 c# .net struct value-type boxing

我最近遇到了这个 Stackoverflow 问题:When to use struct?

在里面,它有一个答案,说的有点深奥:

In addition, realize that when a struct implements an interface - as Enumerator does - and is cast to that implemented type, the struct becomes a reference type and is moved to the heap. Internal to the Dictionary class, Enumerator is still a value type. However, as soon as a method calls GetEnumerator(), a reference-type IEnumerator is returned.

这到底是什么意思?

如果我有类似的东西

struct Foo : IFoo 
{
  public int Foobar;
}

class Bar
{
  public IFoo Biz{get; set;} //assume this is Foo
}

...

var b=new Bar();
var f=b.Biz;
f.Foobar=123; //What would happen here
b.Biz.Foobar=567; //would this overwrite the above, or would it have no effect?
b.Biz=new Foo(); //and here!?

值类型结构被视为引用类型的具体语义是什么?

最佳答案

结构类型的每个声明实际上在运行时声明了两种类型:值类型和堆对象类型。从外部代码的角度来看,堆对象类型将表现得像一个具有相应值类型的字段和方法的类。从内部代码的角度来看,堆类型的行为就像它具有相应值类型的字段 this

尝试将值类型转换为引用类型(ObjectValueTypeEnum 或任何接口(interface)类型)将生成一个新的其对应的堆对象类型的实例,并返回对该新实例的引用。如果试图将值类型存储到引用类型存储位置,或将其作为引用类型参数传递,也会发生同样的事情。一旦该值被转换为堆对象,从外部代码的角度来看,它将表现为堆对象。

唯一可以在不首先将值类型转换为堆对象的情况下使用值类型的接口(interface)实现的情况是,当它作为具有接口(interface)类型作为约束的泛型类型参数传递时。在那种特定情况下,接口(interface)成员可以用在值类型实例上,而不必先将其转换为堆对象。

关于c# - 有关结构实现接口(interface)时发生的情况的详细信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15207260/

相关文章:

c# 类型来处理相对和绝对 URI 和本地文件路径

c# - 检测格式日期

c# - 长异步等待链会导致大量内存消耗吗? (理论上)

c++ - Declspec A Struct,当创建缓冲区以发送到 OpenCL 内核时

c++ - "struct"和结构成员前缺少 "struct"字有什么区别

c# - Unity 处理多个具有不同目的的碰撞器

c# - Excel._Worksheet.Columns.Autofit() 方法挂起

c# - 如何获取 HttpWebRequest 的本地端口号?

.net - 是否有用于 Windows 错误报告的 .Net API

c - 修复了带有空格键和 EOF 检查的字符串