为什么结构不能有析构函数? [英] Why structs cannot have destructors?

查看:336
本文介绍了为什么结构不能有析构函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

什么是面试这种问题,你觉得呢?

What is best answer on interview on such question you think?

我觉得我没有找到这方面的一个副本,在这里,如果有,请联系起来。

I think I didn't find a copy of this here, if there is one please link it.

推荐答案

看这个另一种方式 - 而不是仅仅引用了规范它说,结构不能/不会析构函数 - 考虑是否会发生什么?规范已更改,以便他们做了 - 或者说,让我们问一个问题:我们可以猜测的为什么的那样,语言设计者决定不允许结构有析构函数摆在首位

Another way of looking at this - rather than just quoting the spec which says that structs can't/don't have destructors - consider what would happen if the spec was changed so that they did - or rather, let's ask the question: can we guess why did the language designers decide to not allow structs to have 'destructors' in the first place?

(不要急于选择词析构函数在这里。我们基本上谈论的结构一个神奇的方法,当变量超出作用域被自动调用。换句话说,语言功能类似于C ++的析构函数。)

(Don't get hung up on the word 'destructor' here; we're basically talking about a magic method on structs that gets called automatically when the variable goes out of scope. In other words, a language feature analogous to C++'s destructors.)

要认识到的第一件事是,我们不关心释放内存。无论对象是在堆栈或堆(例如,在一个类中的结构),内存将要采取的一种方式照顾或其它迟早;无论是被弹出堆栈或收集。真正的原因是有一些的析构函数一样摆在首位是管理的的外部资源的 - 比如文件句柄,窗口句柄,或需要特殊处理其他事情,让他们清理了CLR本身不知道的。

The first thing to realize is that we don't care about releasing memory. Whether the object is on the stack or on the heap (eg. a struct in a class), the memory will be taken care of one way or another sooner or later; either by being popped off the stack or by being collected. The real reason for having something that's destructor-like in the first place is for managing external resources - things like file handles, window handles, or other things that need special handling to get them cleaned up that the CLR itself doesn't know about.

现在假设你让一个结构有一个析构函数,可以做到这一点清理。精细。直到你意识到,当结构作为参数传递,他们得到通过值传递的:他们被复制。现在你已经得到的两个的结构具有相同的内部领域,而且他们的两个的去尝试清理相同的对象。其中将首先发生,因此通过后,另一个会开始code奇怪地崩溃......然后它自己的清理将失败(希望 - !最糟糕的情况是,可能在清理其他一些随机的资源取得成功 - 这可以在手柄的值重复使用的情况下,例如发生)

Now supposed you allow a struct to have a destructor that can do this cleanup. Fine. Until you realize that when structs are passed as parameters, they get passed by value: they are copied. Now you've got two structs with the same internal fields, and they're both going to attempt to clean up the same object. One will happen first, and so code that is using the other one afterwards will start to fail mysteriously... and then its own cleanup will fail (hopefully! - worst case is it might succeed in cleaning up some other random resource - this can happen in situations where handle values are reused, for example.)

您可以想见,作出特殊情况下结构是参数,从而使他们的析构函数不要跑(但要小心 - 你现在需要记住,调用函数时,它总是在外面一个'拥有'实际的资源 - 所以现在有些结构是微妙的不同给别人...) - 但你仍然有这个问题,常规结构变量,其中一个可以被分配到另一个,制作副本

You could conceivably make a special case for structs that are parameters so that their 'destructors' don't run (but be careful - you now need to remember that when calling a function, it's always the outer one that 'owns' the actual resource - so now some structs are subtly different to others...) - but then you still have this problem with regular struct variables, where one can be assigned to another, making a copy.

您也许可以解决此通过增加一个特殊的机制来赋值操作,不知怎的,使新的结构进行谈判的基础资源的所有权,其新的副本 - 也许他们分享或直接从旧的所有权转让给新的 - 但现在你已经基本上出发去成C ++ - 土地,在那里你需要拷贝构造函数,赋值运算符,并添加了一个微妙的一堆等待陷阱浑然不知新手程序员。而且请记住,C#中的整个的一点是要避免这种类型的C ++ - 风格的复杂性,尽可能

You could perhaps work around this by adding a special mechanism to assignment operations that somehow allows the new struct to negotiate ownership of the underlying resource with its new copy - perhaps they share it or transfer ownership outright from the old to the new - but now you've essentially headed off into C++-land, where you need copy constructors, assignment operators, and have added a bunch of subtleties waiting to trap the unaware novice programmer. And keep in mind that the entire point of C# is to avoid that type of C++-style complexity as much as possible.

和,只是为了让事情变得更复杂的是,作为其他的答案之一指出,结构不只是存在本地对象。当地人,范围是好的,明确的;但结构也可以是一个类对象的成员。应该在什么时候析构函数被调用在这种情况下?当然,你可以做到这一点时,容器类定稿;但现在你有一个行为会非常不同,具体取决于那里的生活结构的机制:如果结构是一个地方,它就会在范围结束时立即触发;如果结构是一类中,它就会懒洋洋地触发......所以,如果你真的关心确保您的结构的一个部分资源被清除,在一定的时间,如果你的结构可能会最终成为的一员一流的,你会使用()无论如何,以确保你有你的基地覆盖可能需要一些明确的喜欢了IDisposable /。

And, just to make things a bit more confusing, as one of the other answers pointed out, structs don't just exist as local objects. With locals, scope is nice and well defined; but structs can also be members of a class object. When should the 'destructor' get called in that case? Sure, you can do it when the container class is finalized; but now you have a mechanism that behaves very differently depending on where the struct lives: if the struct is a local, it gets triggered immediately at end of scope; if the struct is within a class, it gets triggered lazily... So if you really care about ensuring that some resource in one of your structs is cleaned up at a certain time, and if your struct could end up as a member of a class, you'd probably need something explicit like IDisposable/using() anyhow to ensure you've got your bases covered.

因此​​,虽然我不能说讲的语言的设计者,我可以做一个pretty的好猜,他们决定不包括这样的功能的原因之一是因为它是忌讳的话题,他们想保持C#的相当简单的。

So while I can't claim to speak for the language designers, I can make a pretty good guess that one reason they decided not to include such a feature is because it would be a can of worms, and they wanted to keep C# reasonably simple.

这篇关于为什么结构不能有析构函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆