Val*_*zub 23 .net c# struct destructor finalizer
你认为这个问题的面试最佳答案是什么?
我想我在这里找不到这个副本,如果有的话请链接.
Bre*_*McK 52
另一种看待这种情况的方式 - 而不仅仅是引用说明结构不能/不具有析构函数的规范 - 考虑如果规范被改变以便他们这样做会发生什么 - 或者更确切地说,让我们提出问题:can can我们猜测为什么语言设计师决定不让结构首先出现"析构函数"?
(不要挂在"析构函数"这个词上;我们基本上是在讨论结构上的魔术方法,当变量超出范围时会自动调用.换句话说,语言特征类似于C++的析构函数. )
要意识到的第一件事是我们不关心释放记忆.无论对象是在堆栈上还是在堆上(例如,类中的结构),内存迟早会以这种或那种方式处理; 通过弹出堆栈或收集.首先拥有类似析构函数的东西的真正原因是管理外部资源 - 例如文件句柄,窗口句柄或其他需要特殊处理的东西,以便清理CLR本身不知道的东西.
现在假设您允许结构体具有可以执行此清理的析构函数.精细.直到你意识到结构作为参数传递时,它们才会被值传递:它们被复制.现在你有两个具有相同内部字段的结构,它们都将尝试清理同一个对象.一个将首先发生,因此之后使用另一个的代码将开始神秘地失败...然后它自己的清理将失败(希望! - 最坏的情况是它可能成功清理一些其他随机资源 - 这可以例如,在重复使用句柄值的情况下会发生这种情况.)
你可以设想一个特殊的情况,对于作为参数的结构,它们的'析构函数'不会运行(但要小心 - 你现在需要记住,当调用一个函数时,它始终是'拥有'实际资源的外部函数 - 所以现在一些结构与其他结构略有不同......) - 但是你仍然遇到常规结构变量的问题,其中一个可以分配给另一个,制作副本.
您可以通过向赋值操作添加一种特殊机制来解决这个问题,该机制以某种方式允许新结构与其新副本协商底层资源的所有权 - 也许它们共享它或者将所有权从旧的转移到新的 - 但现在你本质上是进入C++ - land,你需要复制构造函数,赋值运算符,并添加了一堆细微之处,等待陷阱不知不觉的新手程序员.请记住,C#的全部意义在于尽可能避免这种类型的C++风格的复杂性.
并且,正如其他答案所指出的那样,只是为了让事情变得更加混乱,结构不仅仅作为本地对象存在.对于本地人来说,范围很好并且定义明确; 但结构也可以是类对象的成员.在这种情况下应该何时调用"析构函数"?当然,你可以在容器类完成时做到这一点; 但是现在你有一种机制,根据结构所处的位置,行为会有很大不同:如果结构是本地的,它会在范围结束时立即触发; 如果struct在一个类中,它会被懒惰地触发......所以如果你真的关心确保你的某个结构中的某些资源在某个时间被清除,并且你的结构可能最终成为一个成员上课时,你可能需要明确像IDisposable/using()这样的东西,以确保你已经覆盖了你的基础.
因此,虽然我不能声称为语言设计师说话,但我可以很好地猜测他们决定不包含这样一个功能的一个原因是因为它会成为一堆蠕虫,并且他们希望保持C#相当简单.
Cam*_*ner 31
来自Jon Jagger:
"结构体不能有析构函数.析构函数只是object.Finalize
伪装的重写,而结构体,作为值类型,不受垃圾收集的影响."