2010-08-08 74 views
2

我一直在读一些关于immutable structures如string的内容。简而言之,它们一旦创建就不会改变状态(例如,要求子字符串为您提供新字符串)。CLR用不可变结构做什么?

现在,我在想知道CLR是否“知道”某种类型是不可变的,并且在运行时使用这个事实来做一些聪明的事情,或者说不可变性主要是让某些场景更容易编程的东西?

+0

仅供参考:在.net中,'string'不是结构体。这是一个类...一个常规的旧参考类型。 – cHao 2012-05-30 20:50:01

回答

5

一般来说,CLR不会对不可变类型做任何特殊的处理。它们的处理方式与其他类型相同。

对于字符串有特殊的支持。字符串可以被实现并重用。在C#中,源代码字符串文字由编译器自动执行。您也可以通过致电String.Intern自己实习一个字符串。

+1

字符串文字是由编译器实现的,而不是由CLR实现的。有可能用相同字符串的多个副本来产生IL(编译器这样做只是一个坏主意)。 – 2010-08-08 14:05:40

+0

@Jon Hanna:+1 - 对,没错。我已更新我的帖子,以使这一点更加清晰。谢谢。 – 2010-08-08 14:16:00

+1

这是一个挑剔的问题,但是因为querant说CLR,也许他们关心的是那个而不是编译器,否则我什么也没说。有时候,幼儿园可以帮助他成为一名优秀的编码员,而有时候这只会让他成为一个令人讨厌的书呆子。希望这是前者:) – 2010-08-08 14:53:35

0

在CLR的观点中,值是MUTABLE。例如:CLR可以更改对象的数据以执行缓存。 结构的用户无法更改其值,但CLR可以在多种情况下执行此操作。这就是为什么CLR不能在自身上强制执行不可变性并且不能在运行时对其进行中继的原因。

2

潜在地,编译器(而不是CLR)有可能在生成IL时做一些巧妙的事情。我不知道它是否确实如此,并且诚实地不关心:如果它不在将来(更高版本)。如果是这样,也许它不会在将来(一个边缘案例被发现显示优化是不明智的。

我很高兴地想:“好吧,如果这是只读,那么也许编译器或者CLR)会做一些聪明的事情,所以这将是一个免费的改进“,这将是一个改进,因为我永远不会做任何事情只读,以利用这种优化,即使我知道它确实是这样做的,而且这种节省是很好的,如果只读是有意义的,我只会做一些只读的东西。我这样做很多,因为我的风格倾向于大量使用不可变的对象,但我只会做因为对象在逻辑上是不可变的,而不是为了追求某种优化而不可变,然后必须解决不可变性问题。

当然,还有一些方法可以使用不可变对象(特别是在计算不同多线程场景对您的代码的影响时)可以很巧妙地使用

0

编译器和.net都不会对不可变结构做任何事情,它不会与可变结构做任何事情,尽管它只对语义上有效的结构做了一些事情,只有它们碰巧是不可变的。例如,如果将结构强制转换为Object,则编译器将创建一个新的带有与原始数据相同的数据初始化的盒装实例。如果结构是可变的,则新实例在语义上将不会与原始实例相同,因为对一个实例的更改不会影响其他实例。还有其他一些情况,编译器复制结构并假装副本在语义上与原始文件可以互换;不幸的是,我不知道有什么办法可以要求导致这种隐式副本的情况会引起编译时错误,而不是让副本发生。