jjzjj

c# - 不变的还是不可变的?

coder 2024-05-20 原文

好吧,据我所知,不可变 类型本质上是线程安全的,或者我在很多地方都读过,我想我明白为什么会这样。如果实例的内部状态在创建对象后无法修改,那么对实例本身的并发访问似乎没有问题。

因此,我可以创建以下 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();
    }
}

所以问题是:这真的不可变类型吗?真的是线程安全的吗?

显然类型本身是不可变的 但绝对不能保证 T是,因此您可能会遇到与泛型类型直接相关的并发访问和线程问题。这是否意味着 ImmutableList应该被认为是可变的

应该class ImmutableList<T>: IEnumerable<T> where T: struct是唯一真正被认为不可变的类型吗?

感谢您对此问题的任何意见。

更新:很多答案/评论都集中在 ImmutableList 的特定实现上我已经发布了这可能不是一个很好的例子。但问题的关键不是实现。我要问的问题是 ImmutableList<MutableT>考虑到不可变类型所包含的一切,它确实是一个不可变类型。

最佳答案

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.

一般情况下,是的。

Is this really an immutable type?

简要总结一下:您有一个围绕可变列表的写时复制包装器。向不可变列表添加新成员不会改变列表;相反,它会制作底层可变列表的副本,添加到副本,并返回副本周围的包装器。

如果您包装的底层列表对象在读取时不会改变其内部状态,那么您已经满足了“不可变”的原始定义,所以,是的。

我注意到这不是一种非常有效的方式来实现不可变列表。例如,使用不可变的平衡二叉树可能会做得更好。每次制作新列表时,您的草图在时间和内存上都是 O(n);您可以毫不费力地将其改进为 O(log n)。

Is it really thread safe?

前提是底层可变列表对多个读取器是线程安全的,是的。

您可能会感兴趣:

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?.

这是一个哲学问题,而不是技术问题。如果你有一个不可变的人名列表,并且列表永远不会改变,但是其中一个人死了,那么这个列表是“可变的”吗?我认为不会。

如果关于列表的任何问题总是有相同的答案,则列表是不可变的。在我们的人名列表中,“列表中有多少个名字?”是关于列表的问题。 “那几个人还活着?”不是关于列表的问题,而是关于列表所指人员的问题。这个问题的答案会随着时间而改变;第一个问题的答案不是。

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

我没有关注你。将 T 限制为结构如何改变任何事情?好的,T 仅限于结构。我做了一个不可变的结构:

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

现在我做了一个 ImmutableList<S> .是什么阻止我修改存储在 S 实例中的可变数组?仅仅因为列表是不可变的并且结构是不可变的并不会使数组不可变。

关于c# - 不变的还是不可变的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9009627/

有关c# - 不变的还是不可变的?的更多相关文章

  1. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  2. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

  3. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  4. ruby - 如何测试 Ruby 对象是否不可变? - 2

    有没有一种简单的方法来测试一个对象是不可变的(数字,零)还是不可变的(数组,哈希,对象)?换句话说,是否可以通过其他代码的副作用更改它?动机:我想创建一个版本化的值存储,但有些数据是数组。一些数组将存储自定义对象,我可以通过存储“in”属性并搜索它来反转关系。但我也希望能够存储符号数组、其他数组等。 最佳答案 我发现了一个低效的方法:classObjectdefprimitive?beginself.dupfalserescueTypeErrortrueendendend 关于ruby-

  5. c# - C# 中的 Flatten Ruby 方法 - 2

    我如何做Ruby方法"Flatten"RubyMethod在C#中。此方法将锯齿状数组展平为一维数组。例如:s=[1,2,3]#=>[1,2,3]t=[4,5,6,[7,8]]#=>[4,5,6,[7,8]]a=[s,t,9,10]#=>[[1,2,3],[4,5,6,[7,8]],9,10]a.flatten#=>[1,2,3,4,5,6,7,8,9,10 最佳答案 递归解决方案:IEnumerableFlatten(IEnumerablearray){foreach(variteminarray){if(itemisIEnume

  6. ruby - 可以像在 C# 中使用#region 一样在 Ruby 中使用 begin/end 吗? - 2

    我最近从C#转向了Ruby,我发现自己无法制作可折叠的标记代码区域。我只是想到做这种事情应该没问题:classExamplebegin#agroupofmethodsdefmethod1..enddefmethod2..endenddefmethod3..endend...但是这样做真的可以吗?method1和method2最终与method3是同一种东西吗?还是有一些我还没有见过的用于执行此操作的Ruby惯用语? 最佳答案 正如其他人所说,这不会改变方法定义。但是,如果要标记方法组,为什么不使用Ruby语义来标记它们呢?您可以使用

  7. c# - Ruby 等效于 C# Linq 聚合方法 - 2

    什么是Linq聚合方法的ruby​​等价物。它的工作原理是这样的varfactorial=new[]{1,2,3,4,5}.Aggregate((acc,i)=>acc*i);每次将数组序列中的值传递给lambda时,变量acc都会累积。 最佳答案 这在数学以及几乎所有编程语言中通常称为折叠。它是更普遍的变形概念的一个实例。Ruby从Smalltalk中继承了这个特性的名称,它被称为inject:into:(像aCollectioninject:aStartValueinto:aBlock一样使用。)所以,在Ruby中,它称为inj

  8. c# - 先学什么? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭8年前。Improvethisquestion几年前我去学校学习编程,毕业后我找到了一份系统管理方面的工作,这就是我职业生涯的方向。我想重新开始某种开发,并且一直在“玩”C#和ASP.NET,但我已经听到很多关于其他"new"语言的讨论(新的意思是它们是新的)我)喜欢Ruby和F#。我想我想知道我是否在浪费时间学习主要的MS语言,而不是成为一名通才。很长一段时间没有离开开发社区(如果我曾经离开过的话)让我在潮流中挣扎,我不想落在时代的

  9. c# - 在 C# 中重现 Ruby OpenSSL private_encrypt 输出 - 2

    我有一个简单的Ruby脚本,我用它在某些HTTPheader上执行private_encrypt以签署要发送到ruby​​RESTAPI的Web请求,该API会根据Base64编码字符串测试Base64编码字符串生成而不是解码Base64和解密数据然后测试原始字符串。我使用的脚本是require"openssl"require"base64"path_to_cert=ARGV[0].dupplain_text=Base64.decode64(ARGV[1].dup)private_key=OpenSSL::PKey::RSA.new(File.read(path_to_cert))pu

  10. C# 的 LINQ 用于在 ruby​​ 中等效的集合操作 - 2

    我是ruby​​开发的新手,我目前正在使用rails2.3.11在ruby​​1.8.7中开发一个项目,我想知道这种语言是否有与C#的linq等效的集合操作,例如where子句。谢谢。 最佳答案 Ruby中Linq的where等价于find_all检查documentationfortheEnumerableModule用于其他功能。 关于C#的LINQ用于在ruby​​中等效的集合操作,我们在StackOverflow上找到一个类似的问题: https://

随机推荐