不可变的还是不是一成不变的? [英] Immutable or not immutable?

查看:167
本文介绍了不可变的还是不是一成不变的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好吧,我的理解是,一成不变的类型固有的线程安全的,或让我在不同的地方阅读,我想我明白为什么它是如此。如果一旦创建了对象实例的内部状态不能修改似乎与该实例本身的并发访问没有任何问题。



所以,我可以创建以下列表

 类ImmutableList< T>:IEnumerable的< T> ; 
{
只读表< T> innerList;

公共ImmutableList(IEnumerable的< T>收集)
{
this.innerList =新的List< T>(集合);
}

公共ImmutableList()
{
this.innerList =新的List< T>();
}

公共ImmutableList< T>加入(T项目)
{
无功名单=新ImmutableList< T>(this.innerList);
list.innerList.Add(项目);
返回列表;
}

公共ImmutableList< T>删除(T项目)
{
无功名单=新ImmutableList< T>(this.innerList);
list.innerList.Remove(项目);
返回列表;
} //等相关列表的方法...

公共牛逼这个[INT指数]
{
得到
{
返回this.innerList [指数]
}
}

公众的IEnumerator< T>的GetEnumerator()
{
返回innerList.GetEnumerator();
}

System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
回报率((System.Collections.IEnumerable)this.innerList)。的GetEnumerator();
}
}



所以,问题是:这是的真的的一个一成不变的类型?难道真的是线程安全的?



显然类型本身的一成不变的,但也绝对没有garantee的 T 的,因此你可以有直接与泛型类型相关的并发访问和线程问题。请问这意味着 ImmutableList 应考虑的可变的?



应该类ImmutableList< T>:&IEnumerable的LT; T>其中T:?结构真正考虑的唯一类型的一成不变



感谢您对这个问题的任何输入



更新:很多答案/意见集中在具体的实施 ImmutableList 我已经张贴这可能不是一个很好的例子。但问题的问题不是落实。我要问的问题是,如果 ImmutableList< MutableT> 确实是一个不可变的类型考虑,一个不可变型限嗣继承一切


解决方案

如果一旦对象被创建实例的内部状态不能修改似乎与该实例本身的并发访问没有问题。




这是一般的情况,是的。




这真的是一个不可变的类型?




要简要地总结一下:你身边有一个可变的列表中写入时复制包装。添加一个新成员的不可变列表不会发生变异的名单;相反,它使得潜在的可变列表的副本,更增加了拷贝,并返回绕副本的包装。



只要基础列表对象,你是包装不变异其内部状态时,阅读它从,你见过你原来的不可改变的定义,所以,是的。



我注意到,这不是一个非常的有效的方式来实现的不可变列表。可能你有一个不变的平衡二叉树做的更好,例如。草图是在时间和内存每次做一个新上榜时间为O(n);可以提高,为O(log n)的不会有太大困难。




难道真的是线程安全的?




只要底层可变列表是线程安全的多的读者,是的。



这可能会感兴趣你:



http://blogs.msdn.com/b/ericlippert/archive/2011/05/23/read-only-and-threadsafe-are-different.aspx




显然类型本身是不可变的,但也绝对没有garantee T是,所以你可以有直接相关的并发访问和线程问题泛型类型。请问这意味着 ImmutableList< T> 应被视为可变




这是一个哲学问题,不是技术问题。如果您拥有人的名称的不可变列表,该列表不会改变,但人一人死亡,当时的名字可变的名单?我想不会。



一个列表是不可变的,如果任何问题的该列表的总是相同的答案。在我国人民的名单,有多少名就行了?是一部关于名单的问题。 怎么这些人很多都还活着吗?是不是该列表的问题,这是一个有关名单中提到的人的问题。在回答这个问题随时间变化; 。在回答第一个问题并不




如若类 ImmutableList< T>:IEnumerable的< T>其中T:结构

我不跟着你忠实地认为是不变


的唯一类型?如何限制T可为结构改变什么? OK,T仅限于结构。我做一个不变的结构:

 的struct 
{
公众诠释[] {MutableArray获得;私人集; }

}



现在我使一个 ImmutableList< S> 。是什么阻止我从修改存储在的S情况下,可变数组?只是因为名单是不可改变的,这个结构是不可变的不会使阵列一成不变的。


Ok, as I understand it, immutable types are inherently thread safe or so I've read in various places and I think I understand why it is so. If the inner state of an instance can not be modified once the object is created there seems to be no problems with concurrent access to the instance itself.

Therefore, I could create the following List:

class ImmutableList<T>: IEnumerable<T>
{
    readonly List<T> innerList;

    public ImmutableList(IEnumerable<T> collection)
    {
         this.innerList = new List<T>(collection);
    }

    public ImmutableList()
    {
         this.innerList = new List<T>();
    }

    public ImmutableList<T> Add(T item)
    {
         var list = new ImmutableList<T>(this.innerList);
         list.innerList.Add(item);
         return list;
    }

    public ImmutableList<T> Remove(T item)
    {
         var list = new ImmutableList<T>(this.innerList);
         list.innerList.Remove(item);
         return list;
    } //and so on with relevant List methods...

    public T this[int index]
    {
        get
        {
            return this.innerList[index];
        }
    }

    public IEnumerator<T> GetEnumerator()
    {
        return innerList.GetEnumerator();
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return ((System.Collections.IEnumerable)this.innerList).GetEnumerator();
    }
}

So the question is: Is this really an immutable type? Is it really thread safe?

Obviously the type itself is immutable but there is absolutely no garantee that T is and therefore you could have concurrent access and threading issues related directly with the generic type. Would that mean that ImmutableList should be considered mutable?.

Should class ImmutableList<T>: IEnumerable<T> where T: struct be the only type truly considered immutable?

Thanks for any input on this issue.

UPDATE: A lot of answers/comments are concentrating on the particular implementation of ImmutableList I've posted which is probably not a very good example. But the issue of the question is not the implementation. The question I'm asking is if ImmutableList<MutableT> is really an immutable type considering everything that an immutable type entails.

解决方案

If the inner state of an instance can not be modified once the object is created there seems to be no problems with concurrent access to the instance itself.

That is generally the case, yes.

Is this really an immutable type?

To briefly sum up: you have a copy-on-write wrapper around a mutable list. Adding a new member to an immutable list does not mutate the list; instead it makes a copy of the underlying mutable list, adds to the copy, and returns a wrapper around the copy.

Provided that the underlying list object you are wrapping does not mutate its internal state when it is read from, you have met your original definition of "immutable", so, yes.

I note that this is not a very efficient way to implement an immutable list. You'd likely do better with an immutable balanced binary tree, for example. Your sketch is O(n) in both time and memory every time you make a new list; you can improve that to O(log n) without too much difficulty.

Is it really thread safe?

Provided that the underlying mutable list is threadsafe for multiple readers, yes.

This might be of interest to you:

http://blogs.msdn.com/b/ericlippert/archive/2011/05/23/read-only-and-threadsafe-are-different.aspx

Obviously the type itself is immutable but there is absolutely no garantee that T is and therefore you could have concurrent access and threading issues related directly with the generic type. Would that mean that ImmutableList<T> should be considered mutable?.

That's a philosophical question, not a technical one. If you have an immutable list of people's names, and the list never changes, but one of the people dies, was the list of names "mutable"? I would think not.

A list is immutable if any question about the list always has the same answer. In our list of people's names, "how many names are on the list?" is a question about the list. "How many of those people are alive?" is not a question about the list, it is a question about the people referred to by the list. The answer to that question changes over time; the answer to the first question does not.

Should class ImmutableList<T>: IEnumerable<T> where T: struct be the only type truely considered immutable?

I'm not following you. How does restricting T to be a struct change anything? OK, T is restricted to struct. I make an immutable struct:

struct S
{
    public int[] MutableArray { get; private set; }
    ...
}

And now I make an ImmutableList<S>. What stops me from modifying the mutable array stored in instances of S? Just because the list is immutable and the struct is immutable doesn't make the array immutable.

这篇关于不可变的还是不是一成不变的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆