C# CLR对不可变结构做什么?

C# CLR对不可变结构做什么?,c#,.net,immutability,C#,.net,Immutability,我读了一些关于字符串的书。简单地说,它们创建后不会改变状态(例如,请求一个子字符串会给您一个新字符串) 现在,我想知道CLR是否“知道”某个类型是不可变的,并利用这一事实在运行时做了一些巧妙的事情,或者说不可变主要是使某些场景更易于编程的事情?一般来说,CLR对不可变类型没有任何特殊的处理。它们的处理方式与任何其他类型相同 对于字符串有特殊的支持。字符串可以被插入和重用。在C#中,源代码字符串文本由编译器自动插入。您也可以通过调用来插入字符串。在CLR的透视图中,值是可变的。例如:CLR可以更改

我读了一些关于字符串的书。简单地说,它们创建后不会改变状态(例如,请求一个子字符串会给您一个新字符串)


现在,我想知道CLR是否“知道”某个类型是不可变的,并利用这一事实在运行时做了一些巧妙的事情,或者说不可变主要是使某些场景更易于编程的事情?

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


对于字符串有特殊的支持。字符串可以被插入和重用。在C#中,源代码字符串文本由编译器自动插入。您也可以通过调用来插入字符串。

在CLR的透视图中,值是可变的。例如:CLR可以更改对象的数据以执行缓存。
该结构的用户不能更改其值,但CLR可以在几种情况下进行更改。这就是为什么CLR不能在自身上实施不变性,也不能在运行时依赖它。

编译器(而不是CLR)可能会在生成IL时巧妙地利用它。我不知道是否有,老实说,我也不在乎:如果没有,也许将来会有。如果是这样,也许将来不会(发现一个edge案例表明优化是不明智的

我很高兴想到“如果这是只读的,那么编译器(或者说CLR)可能会用它做一些聪明的事情,所以这将是一个免费的改进”。这将是一个免费的改进,因为我永远不会为了利用这种优化而制作一些只读的东西,即使我知道它肯定会这样做,而且节省了很多钱。我只会在只读有意义的情况下制作一些只读的东西。我经常这样做,因为我的风格喜欢大量使用immuta不可更改的对象,但我只会这样做,因为对象在逻辑上是不可更改的,而不是为了追求某种优化而使其不可更改,然后必须绕过不可更改性


当然,您也可以通过某些方式巧妙地处理不可变对象(特别是在计算不同多线程场景对代码的影响时).

编译器和.net都不会对不可变结构执行任何与不可变结构不同的操作,尽管它会对仅当结构恰好不可变时才在语义上有效的结构执行某些操作。例如,如果将结构强制转换为对象,编译器将创建结构initiali的新装箱实例使用与原始实例相同的数据进行编译。如果结构是可变的,则新实例在语义上与原始实例不同,因为对一个实例的更改不会影响另一个实例。在其他一些情况下,编译器复制结构并假装副本在语义上与原始实例可互换;不幸的是ely,我不知道有什么方法可以要求导致这种隐式复制的情况应该引起编译时错误,而不是让复制发生。

字符串文本由编译器而不是CLR进行保存。使用同一字符串的多个副本生成IL是可能的(编译器这样做是个坏主意)@Jon Hanna:+1-是的,没错。我已经更新了我的帖子,让这一点更清楚。谢谢。这有点吹毛求疵,但既然质询者说CLR,也许他们关心的是CLR,而不是编译器,否则我什么也不会说。有时候学究帮助一个人成为一个好的程序员,有时候它只是让一个人成为一个讨厌的学究。H实际上,这是前者:)供参考:在.net中,
string
不是结构。这是一个类…一个常规的旧引用类型。