为什么不是';对于其他不可变类型,没有等价的StringBuilder
本文关键字:类型 不可变 StringBuilder 其他 于其他 为什么不 | 更新日期: 2023-09-27 18:20:15
StringBuilder的存在纯粹是因为.NET中的字符串是不可变的,也就是说,传统的字符串串联可能会使用大量资源(因为创建了大量的string对象)。
那么,既然Int32也是不可变的为什么不存在用于多重加法的类呢?
有。有用于构建Uri
对象的UriBuilder
。
Int32Builder
会做什么?通过使用这样的类,对单个整数进行什么有意义的运算会更方便和/或更具性能?
为了使XXXBuilder类有意义,必须满足以下条件:
- 类或结构是不可变的
- 通过将其替换为基于先前的值(例如
someString += "abc"
或someDate = someDate.AddDays(1)
)来改变该值必须相对昂贵(在前一示例中确实比后一示例更昂贵)和/或相对复杂 - 对这样一个XXXBuilder类的需求非常普遍,因此提供它是有意义的,而不仅仅是让那些需要它的人自己编写代码
以上内容均不适用于int
。它们确实适用于string
和Uri
。我不认为引用与值类型特别相关,除了点2适用的情况下,类几乎肯定是比值类型更好的设计选择。
事实上,点1和点2的组合在.NET中相对不常见。有些人会认为它不太常见(那些喜欢大量使用不可变类型的人)。如果我们能避开第二点,那么我们会的,不是吗?没有人会认为"我会把这个代码编写得既昂贵又笨拙,并提供一个构建器类"。相反,他们有时可能会认为"我深思熟虑的不变性的缺点是,虽然它给了我很多优势,但它会使一些操作变得昂贵和笨拙,所以我也会提供一个生成器类"。
串联的字符串会变长,这需要堆内存分配和内存拷贝
字符串越长,它们的成本就越高,因此我们有一个辅助类(即StringBuilder
)来最大限度地减少字符串串接时的复制量。
Ints不是concatinated的,当你乘int时,你不需要更多的内存来保存两个乘int的结果,你只需要另一个int(或者如果是*=
,则是同一个int)。
如果需要将int连接到某种形式的列表中,则只需要一个helper类。哦,等等,List<int>
!
Int32
是值类型。
String
是引用类型。StringBuilder
存在,因为String
是一个不可变的引用类型。String
也是Char
的集合-连接字符串时会发生很多分配-StringBuilder
会提前进行这些分配,从而使连接字符串的创建更加高效。这不是值类型的问题。
因为Int32是一种值类型,通常在堆栈上(或堆对象的主体内)分配。例如,当在循环中添加许多值类型时,编译器将自动重用内存位置。
答案基本上是"因为一个实现细节,这意味着它是不必要的"。
字符串串联很慢,导致需要StringBuilder
,这本身就是一个实现细节。
可以跟踪值类型的生存期,因为它们具有值类型语义。是否发生这种情况是一个实现细节。在实践中确实如此,这就是为什么不需要IntBuilder类的原因。