什么是可变类。我们如何在C#中创建一个可变且不可变的类
我在CMMI 5级公司采访中被问到如何在C#中创建一个可变和不可变类。我听说过的可变和不可变这意味着可以改变和不能改变,像字符串和StringBuilder的。什么是可变类。我们如何在C#中创建一个可变且不可变的类
但是,我不知道如何创建一个可变类和不可变类。我们有String和String构建器。但是当创建一个,我被迫在网上搜索这个,但找不到任何有用的,所以想到这里问。
但是,我试图通过在类中定义一个属性并在其Getter上创建它,我创建了一个新的字符串对象来复制它。但没有成功理解。
此外,我已经提到了一个问题已经在stackoverflow中提出了关于不可变和可变的问题。但是,我的问题是不同的。我想知道如果我想创建一个可变类,那么除了使用String或其他可变类之外,我将如何使用它。
C#没有与const
相同的支持水平 - C++提供的正确性(忽略代码合同),但它仍然提供readonly
修饰符(以及C#6.0中真正的只读自动属性),这有助于。
C#也缺乏对Record类型的语法支持,但不幸的是它们是从C#7中提取的,所以我们不得不再等一年。
无论如何,.NET中的不可变类型只是一个POCO,它在构造后不能修改其状态。请注意,只有编译器或运行时才会执行此操作,前提是您的类型的每个字段都标记为readonly
,并且每个复杂(即非标量)成员也都受到类似限制。噢,你不能有任何数组成员,因为在C#中没有强制只读缓冲区。这意味着在实践中,C#中的“不可变”类型只是一个设计良好的POCO,消费者(按照规则玩游戏的人)可以对使用它时做出某些假设,例如,不可变类型本质上是线程安全的。但就是这样。没有特殊的AOT或JIT优化,也没有运行时显示的任何特殊行为。这是一个非常“人为因素” - 信达的事情。
下面这个类是不可变的:
class Immutable {
private readonly String foo;
public Immutable(String foo, String bar) {
this.foo = foo;
this.Bar = bar;
}
public String Bar { get: }
public String Baz { get { return this.foo.Substring(0, 2); } }
}
这是不可改变的,因为每场(即它的实例状态)既readonly
和不可改变的(我们只知道这是因为System.String
是众所周知的是不可变的)。如果foo
改为StringBuilder
或XmlElement
那么它将不再是不可变的。
注意,严格来说,readonly
修改不需要更改的,它只是可以更容易地证明,它确实为编译时执行的一些级别(和可能一些运行时优化)。
为了比较起见,该类不是不可变的(即,它是可变的):
class Mutable {
private readonly Int32[] values;
public Mutable(Int32 values) {
this.values = values;
}
public Int32[] GetValues() {
return this.values;
}
}
它是可变的,因为:
-
Int32[]
(数组类型)是可变的 - 它返回经由
GetValues
- 一个参照可变数组它接受一个施工期间可变对象参数。
下面是一个例子证明,为什么它不是一成不变的:使用Mutable
的API时
Int32[] values = { 0, 1, 2, 3 };
Mutable mutable = new Mutable(values);
Print(mutable.GetValues()); // prints "0, 1, 2, 3"
values[0] = 5;
Print(mutable.GetValues()); // prints "5, 1, 2, 3"
如果Mutable
是不可变的那么后续更改values
将不可见:以Print
第二个电话会显示与第一个相同的输出。
但是,即使使用数组或复杂类型,也可以拥有不可变类型:这是通过隐藏修改状态的所有方法完成的。例如,返回ReadOnlyCollection<Int32>
而不是Int32[]
,并始终对传入的所有复杂值和可变值执行深度复制/克隆。但是,编译器,JIT和运行时仍然不够复杂,无法确定这会呈现对象类型不可变 - 因此,为什么必须记录它并相信消费者才能正确使用它(或者如果您是消费者,请相信您的上游设备他们正确实施它)
可能重复[有什么区别mutable和不可变?](http://stackoverflow.com/questions/3811016/what-is-the-difference-between-mutable-and-不可变) – walther
请在发布之前搜索答案,以免发生重复问题。 – walther
@walther:请阅读我的问题!我问了如何创建一个可变类。我知道什么是可变的和不可变的。但是当谈到创作时,我不知道它。和你提到的问题是不同的! – Yash