我目前正在一家大量使用Spring Dependency Injection的商店里重读"Effective Java".在阅读布洛赫的书时,人们不禁会发现他对课堂不变性的强调(他多次表示课程应尽可能不变).我不禁感到这与Spring Dependency Injection(以及大多数DI引擎)对javabeans标准的依赖直接冲突.阅读"Spring in Action"关于DI的章节似乎会让Bloch畏缩他们的可变类,这些类由在你职权范围之外实例化的对象组成,这些对象本身就是可变的.
是不是Bloch的想法对于Spring来说太新颖了?Spring模型被破坏了吗?Bloch对不变性的立场是否仅适用于编写库代码?在编写Spring代码时,我应该编写带有大量getter和setter的灵活对象,还是在构造函数中加载所有内容?
锁定状态很棒.在C#中,一旦构造函数通过声明为完成,就可以确保字段不会更改它的值/引用readonly.
class Foo
{
private readonly string _foo;
public Foo() {
_foo = "Unchangeable";
}
public void ChangeIt() {
_foo = "Darn"; // compiler error
}
}
Run Code Online (Sandbox Code Playgroud)
我可以用C++做同样的事情吗?如果是这样,怎么样?如果没有,为什么不呢?
在Real World Haskell中,有一个标题为"没有数组或哈希表的生命"的部分,作者建议列表和树在函数式编程中是首选,而数组或哈希表可能在命令式程序中使用.
这是有道理的,因为在创建新列表或树时,重用部分(不可变)列表或树要比使用数组更容易.
所以我的问题是:
我在我的应用程序中创建了大多数基本类型,不可变.但收藏品是否也应该是不可变的?对我来说,这似乎是一个巨大的开销,除非我错过了什么.
我在谈论集合以保存Point3值等,可以在不同时间添加它们.因此,如果集合中有1M值,并且您需要删除其中的1个,则必须重新创建相同的集合,对吧?
我有一个列表,我想提供对包含其内容的集合的只读访问权限.我怎样才能做到这一点?
就像是:
public ICollection<Foo> ImmutableViewOfInventory() {
IList<Foo> inventory = new List<Foo>();
inventory.add(new Foo());
return inventory.ImmutableView();
}
Run Code Online (Sandbox Code Playgroud)
另外,一个不可变的IEnumerable也没关系.
更新:我现在意识到列表的不可变视图实际上会更好.(保留列表排序语义.)
这不会给我列表行为,对:
public ReadOnlyCollection<PickUp> InventoryItems()
{
return new ReadOnlyCollection<PickUp>(inventory);
}
Run Code Online (Sandbox Code Playgroud)
我正在查看文档,但没有立即看到ReadOnlyList<T>.
一旦我研究了字符串不可变的优点,因为有些东西可以改善内存中的性能.
任何人都可以向我解释一下吗?我在互联网上找不到它.
我有一个不可变的递归类型:
public sealed class Foo
{
private readonly object something;
private readonly Foo other; // might be null
public Foo(object something, Foo other)
{
this.something = something;
this.other = other;
}
public object Something { get { return something; } }
public Foo Other { get { return other; } }
}
Run Code Online (Sandbox Code Playgroud)
我需要实例化这种相互引用的两个对象,即a.Other == b && b.Other == a.
我不想放弃不变性不变量,因为Foo它旨在用作flyweight.我可以(并且我认为必须)放弃readonly这些字段,并保持"胆量"可变,但公共接口必须是不可变的.
是冰棍不变性来完成这件事的唯一途径?
我正在尝试为一系列类型建模.每种类型都有一个名称和几个属性.每个属性都有一个名称和一个类型.有一些相互递归的类型,这就是出现这个问题的地方.
我应该尽可能让我的课程不变吗?
我曾经读过Joshua Bloch撰写的"Effective Java"一书,他建议出于各种原因使所有业务对象不可变.(例如线程安全)这是否也适用于C#?
您是否尝试使对象不可变,因此在使用它们时遇到的问题较少?或者不值得为此创造它们带来的不便?
您能否澄清一下,为什么 在课堂上我们将最终关键字作为不可变关键字时需要它.我的意思是,如果我们将所有属性声明为private和final,那么它也是一个不可变类,不是吗?
对不起,如果问题看起来很容易,但我真的很困惑.帮帮我.
Editted:我知道一个声明final的类不能被子类化.但是如果每个属性都是私有的,那么最终会有什么区别呢?
以下是类与C#中的结构不同的唯一方法(如果我错了请纠正我):
假设我有一个不可变的结构,即包含初始化后无法修改的字段的结构.每次我将此结构作为参数传递或在赋值中使用时,该值都将被复制并存储在堆栈中.
然后假设我使这个不可变的结构成为一个不可变的类.此类的单个实例将创建一次,并且只有对类的引用将被复制到赋值和参数传递中.
如果对象是可变的,则这两种情况下的行为会有所不同:当一个人改变对象时,在第一种情况下,结构的副本将被修改,而在第二种情况下,原始对象将被改变.但是,在这两种情况下,对象都是不可变的,因此这个对象的用户实际上是类还是结构没有区别.
由于复制引用比复制struct便宜,为什么要使用不可变结构?
此外,由于可变结构是邪恶的,看起来根本没有理由使用结构.
我哪里错了?