为什么C#中没有声明性的不变性?

时间:2022-03-29 13:50:15

Why the designers of C# did not allow for something like this?

为什么C#的设计者不允许这样的东西?

public readonly class ImmutableThing
{
    ...
}

One of the most important ways to safe multi-threading is the use of immutable objects/classes, yet there is no way to declare a class as immutable. I know I can make it immutable by proper implementation but having this enforced by class declaration would make it so much easier and safer. Commenting a class as immutable is a "door prop" solution at best.

安全多线程最重要的方法之一是使用不可变对象/类,但是没有办法将类声明为不可变。我知道我可以通过正确的实现使其不可变但是通过类声明强制执行会使它变得更容易和更安全。将一个类评为不可变是最好的“门支柱”解决方案。

One look at a class declaration and you would instantly know it was immutable. If you had to modify someone else's code you would know a class does not allow changes by intent. I can only see advantages here but I can't believe no one thought about this before. So why is not supported?

看一下类声明,你会立即知道它是不可变的。如果您必须修改其他人的代码,您就会知道某个类不允许按意图进行更改。我只能在这里看到优势,但我不敢相信没有人想过这个。那么为什么不支持?

EDIT

编辑

Some say this is not very important feature but that does not really convince me. Multicore processors showed up because increasing performance by frequency hit a wall. Supercomputers are heavily multiprocessor machines. Parallel processing is more and more important and is one of the main ways to improve performance. The support for multithreading and parallel processing in .NET is significant (various lock types, thread pool, tasks, async calls, concurrent collections, blocking collection, parallel foreach, PLINQ and so on) and it seems to me everything that helps you write parallel code more easily gives an edge. Even if it's non trivial to implement.

有人说这不是一个非常重要的功能,但这并不能说服我。多核处理器出现了,因为频率提高了性能。超级计算机是多处理器的重要机器。并行处理越来越重要,是提高性能的主要方法之一。 .NET中对多线程和并行处理的支持很重要(各种锁类型,线程池,任务,异步调用,并发集合,阻塞集合,并行foreach,PLINQ等),在我看来,一切都可以帮助你编写并行代码更容易给出优势。即使实施它也是微不足道的。

2 个解决方案

#1


12  

Basically, because it's complicated - and as usr wrote, features need a lot of work in various ways before they're ready to ship. (It's easy being an armchair language designer - I'm sure it's incredibly difficult to really do it, in a language with millions of developers with critical code bases which can't be broken by changes.)

基本上,因为它很复杂 - 正如我们所写的那样,功能在准备发布之前需要以各种方式进行大量工作。 (很容易成为一名扶手椅语言设计师 - 我确信这样做非常困难,因为这种语言有数百万开发人员具有关键代码库,这些代码库无法通过更改来解决。)

It's tricky for a compiler to verify that a type is visibly-immutable without being overly restrictive in some cases. As an example, String is actually mutable within mscorlib, but the code of other types (e.g. StringBuilder) has been written very carefully to avoid the outside world ever seeing that mutability.

编译器在某些情况下验证类型是否明显不可变而不过度限制是很棘手的。作为一个例子,String在mscorlib中实际上是可变的,但是其他类型的代码(例如StringBuilder)已经非常仔细地编写,以避免外部世界看到这种可变性。

Eric Lippert has written a lot on immutability - it's a complex topic which would/will need a lot of work to turn into a practical language feature. It's also quite hard to retrofit onto a language and framework which didn't have it to start with. I'd love C# to at least make it easier to write immutable types, and I suspect the team has spent quite a while thinking about it - whether they'll ever be happy enough with their ideas to turn it into a production language feature is a different matter.

Eric Lippert撰写了很多关于不变性的文章 - 这是一个复杂的话题,需要大量的工作才能变成实用的语言功能。对于一个没有开始的语言和框架进行改造也很困难。我喜欢C#,至少可以更容易地编写不可变类型,我怀疑团队已经花了很长时间来思考它 - 他们是否会对他们的想法变得足够快乐将其变成生产语言功能是另一件事。

#2


5  

Features need to be designed, implemented, tested, documented, deployed and supported. That's why we get the most important features first, and the less important ones late or never.

需要设计,实施,测试,记录,部署和支持功能。这就是为什么我们首先获得最重要的功能,而不是最重要的功能是迟到或永远不会。

Your proposal is ok, but there is an easy workaround (as you said). Therefore it is not an "urgent" feature.

您的建议没问题,但有一个简单的解决方法(正如您所说)。因此,它不是一个“紧急”的功能。

There is also a thing called representational immutability where state mutations inside the object are allowed but are never made visible to the outside. Example: a lazily-calculated field. This would not be possible under your proposal because the compiler could never prove the class to be immutable to the outside, although its field are routinely written to.

还有一种称为代表不变性的东西,其中允许对象内部的状态突变但是从不对外部可见。示例:延迟计算的字段。根据您的提议,这是不可能的,因为编译器永远不会证明该类对外部是不可变的,尽管它的字段是常规写入的。

#1


12  

Basically, because it's complicated - and as usr wrote, features need a lot of work in various ways before they're ready to ship. (It's easy being an armchair language designer - I'm sure it's incredibly difficult to really do it, in a language with millions of developers with critical code bases which can't be broken by changes.)

基本上,因为它很复杂 - 正如我们所写的那样,功能在准备发布之前需要以各种方式进行大量工作。 (很容易成为一名扶手椅语言设计师 - 我确信这样做非常困难,因为这种语言有数百万开发人员具有关键代码库,这些代码库无法通过更改来解决。)

It's tricky for a compiler to verify that a type is visibly-immutable without being overly restrictive in some cases. As an example, String is actually mutable within mscorlib, but the code of other types (e.g. StringBuilder) has been written very carefully to avoid the outside world ever seeing that mutability.

编译器在某些情况下验证类型是否明显不可变而不过度限制是很棘手的。作为一个例子,String在mscorlib中实际上是可变的,但是其他类型的代码(例如StringBuilder)已经非常仔细地编写,以避免外部世界看到这种可变性。

Eric Lippert has written a lot on immutability - it's a complex topic which would/will need a lot of work to turn into a practical language feature. It's also quite hard to retrofit onto a language and framework which didn't have it to start with. I'd love C# to at least make it easier to write immutable types, and I suspect the team has spent quite a while thinking about it - whether they'll ever be happy enough with their ideas to turn it into a production language feature is a different matter.

Eric Lippert撰写了很多关于不变性的文章 - 这是一个复杂的话题,需要大量的工作才能变成实用的语言功能。对于一个没有开始的语言和框架进行改造也很困难。我喜欢C#,至少可以更容易地编写不可变类型,我怀疑团队已经花了很长时间来思考它 - 他们是否会对他们的想法变得足够快乐将其变成生产语言功能是另一件事。

#2


5  

Features need to be designed, implemented, tested, documented, deployed and supported. That's why we get the most important features first, and the less important ones late or never.

需要设计,实施,测试,记录,部署和支持功能。这就是为什么我们首先获得最重要的功能,而不是最重要的功能是迟到或永远不会。

Your proposal is ok, but there is an easy workaround (as you said). Therefore it is not an "urgent" feature.

您的建议没问题,但有一个简单的解决方法(正如您所说)。因此,它不是一个“紧急”的功能。

There is also a thing called representational immutability where state mutations inside the object are allowed but are never made visible to the outside. Example: a lazily-calculated field. This would not be possible under your proposal because the compiler could never prove the class to be immutable to the outside, although its field are routinely written to.

还有一种称为代表不变性的东西,其中允许对象内部的状态突变但是从不对外部可见。示例:延迟计算的字段。根据您的提议,这是不可能的,因为编译器永远不会证明该类对外部是不可变的,尽管它的字段是常规写入的。