首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么实现 .NET 的 ICollection 集合时需要实现 SyncRoot 属性?如何正确实现这个属性

非泛型版本的 ICollection 中有 IsSynchronized 属性和 SyncRoot 属性,这两个属性被用来设计成以线程安全的方式访问和修改集合。...虽然泛型版本的 ICollection 已经改进了设计,不再引入 SyncRoot 这样的属性到接口中,但如果我们在某些场景下需要实现 ICollection 非泛型集合时,如何正确实现 SyncRoot...而 ICollection 接口中的 SyncRoot 属性在接口中必然是公开的,于是没有任何途径可以保证调用方不会发生死锁。...结合 .NET Core 源代码的一些常用写法,给出一个推荐的 SyncRoot 模式的写法: // Is this List synchronized (thread-safe)?...然而这个属性都是 public 了,不管返回什么,与 this 还有什么区别…… 关于为什么同步时不应该返回 this 或者返回公开的对象,原因可以看我的另一篇博客: 为什么不应该公开用来同步的加锁对象

81030

编写高质量代码改善C#程序的157个建议

建议24、迭代器应该是只读的  前端时间在实现迭代器的时候就发现了这样一个问题,迭代器只有GetEnumeratior方法,没有SetEnumerator方法。...所有的集合也没有一个可写的迭代器属性。原来这里面室友原因的: 其一:这违背了设计模式的开闭原则。被设置到集合的迭代可能会直接导致集合的行为发生异常或变动。...由于集合属性是一个引用类型,而当前针对该属性对象的引用却有两个,即集合本身和调用者的类型变量list。   ...在例子,我们将list赋值为null,模拟在StudentTeamA(或者说工作线程t1)不知情的情况下使得集合属性变为null。...下面我们对上面的代码做一个简单的修改,首先,将类型的集合属性设置为只读,其次,集合对象由类型自身创建,这保证了集合属性永远只有一个引用: public class Student {

56130
您找到你想要的搜索结果了吗?
是的
没有找到

C#集合类型大揭秘

我们可以将迭代器想象成数据库的游标,即序列(集合)的某个位置,迭代器只能在序列(集合)向前移动。...集合类直接支持 IEnumerator 和 IEnumerator 接口。...借助 Length 属性,C# 编译器可以使用 for 语句迭代数组的每个元素。for适用于长度固定且始终支持索引运算符的数组,但并不是所有类型集合的元素数量都是已知的。...主要扩展的功能有: 新增了属性Count,用于记录集合元素个数 支持添加元素和移除元素 支持是否包含某元素 支持清空集合等等 对于任何实现了**ICollection**接口的集合,我们都可以通过第1条...如果您认为还不错,不妨关注一下的【微信公众号】,第一时间获取文章更新。转载与引用请注明出处。

1.1K70

C#语言各种集合介绍

大家好,又见面了,是全栈君 集合,表示可以通过遍历每个元素来访问的一组对象(特别是可使用foreach循环访问) 一个集合包括多个元素,即有一个集合类对象和N个元素对象 因为任何集合类都实现了IEnumerable...派生于IEnumerable 它定义了集合类最基本的行为,所有的集合类都实现了这个接口(基接口) 但是它的行为太过基本:主要就是一个Count属性,单独实现它没有太大意义 2)IEnumerable 公开枚举数...但不能预先知道数组的大小,就可以使用ArrayList ArrayList把所有元素都当作object对象引用,因而在访问ArrayList的元素时要进行类型转换 优点:动态改变大小、灵活方便的插入和删除元素...3)Hashtable 实现了接口:IDictionary、ICollection、IEnumerable 可以向Hashtable自由添加和删除元素,有些像ArrayList,但没有那么大的性能开销...对象,来遍历队列的各个元素 6)Stack 实现了接口:ICollection、IEnumerable Stack是堆栈,后进先出的访问各个元素 可以调用Stack对象的GetEnumerator()

59721

VsxHowTo -- 把Windows Forms Designer作为自己的编辑器(2)

控件自动命名 从toolbox里拖入一个控件时,如果想让控件自动命名,我们需要往DesignerHost里加一个INameCreationService的服务,没有研究过为什么BasicDesignerLoader...默认帮我们加上,不过好在msdn上有一个例子,稍微简化了一下它,如下: using System;using System.ComponentModel;using System.ComponentModel.Design.Serialization...)serializationData); } return null; } public object Serialize(ICollection...,当然,在这之前,我们需要修改一下DesignerLoader的构造函数,以便我们可以取得DocumentData的引用: class DesignerLoader : BasicDesignerLoader...不过要注意的是Control的部分属性是没有必要序列化到文件里的,所以在序列化的时候要过滤些属性,例如根据BrowsableAttribute来决定哪些属性可以被序列化。

39120

.net源码分析 – List

ICollection是集合接口,支持着集合的Count属性和CopyTo操作,另外还有同步的属性IsSynchronized(判断是否线程安全)和SyncRoot(lock的对象)。...泛型部分基本是上面这些接口的泛型实现,不过IList的一些操作放到ICollection里了,可能微软也觉得对于集合的一些操作放到ICollection更合理吧。...如果不是ICollection,不过由于是IEnumerable,所以可以遍历,一个一个加到_items里。 属性 Count 返回的是_size,这个是元素的实际个数,不是数组大小。...List不是线程安全,需要我们自己用锁搞定, IsReadOnly也是false, 那为什么要继承IReadOnlyList呢,是为了提供一个转换成只读List的机会,比如有的方法希望传进来的...另外用到version还有枚举器Enumerator,MoveNext过程同样会检测这个。

70580

dotnet 双缓存数据结构设计 下载库的文件写入缓存框架

在写一个文件下载库,这个下载库利用断点续传机制,支持多线程下载一个文件。但是文件写入只能支持单线程,不想让网络下载需要等待磁盘写入,因此需要先在内存做缓存,然后让磁盘写入。...可以使用下面代码给项目添加下载库的引用 dotnet add package dotnetCampus.FileDownloader 使用方法如下 var segmentFileDownloader...,不期望网络下载需要等待磁盘下载,因此抄袭了 DirectX 的设计方法,开了一个双缓存。...,这个属性将会指向 AList 或 BList 其中一个值 private T CurrentList { set; get; } 在初始化的时候将会初始化这三个属性 public...调用的时候返回的集合不能被保存,也就是如下代码是推荐的 private void Foo() { Buffer = fooDoubleBuffer.SwitchBuffer(); } private

52320

.NET的泛型集合

接下来是ICollection,它扩展了IEnumerable,添加了两个属性(Count和IsReadOnly)、变动方法(Add、Remove和Clear)、CopyTo(将内容复制到数组)和Contains...通常倾向于将接口作为方法和属性的返回类型,而不是保证一个特定的实现类。在API公开易变集合之前,你也应该深思熟虑,特别是当集合代表的是对象或类型的状态时。...它是经典的计算机科学的双向链表:包含头节点和尾节点,每个节点都包含对链表前一个节点和后一个节点的引用。...HashMap默认加载因子为什么选择0.75?...选择0.75作为默认的加载因子,完全是时间和空间成本上寻求的一种折衷选择, 正文 前几天在一个群里看到有人讨论hashmap的加载因子为什么是默认0.75。

16320

自定义值类型一定不要忘了重写Equals,否则性能和空间双双堪忧

do 打出来,说明这些都是引用类型。。。这些引用类型哪里来的?...寻找ValueType的Equals实现 为什么会这样呢?...改进方案 问题找到了,解决起来就简单了,走这个通用的 equals 不就行啦,自定义一个equals方法,然后跑一下代码。...从输出结果看,还是走了通用的equals方法,这就尴尬了,为什么会这样呢? 2. 从FCL的值类型实现上寻找问题 有时候苦思冥想找不出问题,突然灵光一现,FCL也有一些自定义值类型吗?...从List的Contains源码寻找答案 好奇心再次驱使寻找List是如何做到的,为了能看到List中原生方法,修改代码如下,从Contains方法入手。

32320

《CLR via C#》笔记:第3部分 基本类型(2)

这意味着数组始终是引用类型,是在托管堆上分配的。在应用程序的变量或字段,包含的是对数组的引用,而不是包含数组本身的元素。...(P329 1) (不明白C#为什么不像C++那些创建数组的看这里)第一行代码声明myIntegers变量,它能指向包含Int32值的一维数组。...Copy方法还能在复制每个数组元素时进行必要的类型转换,具体如下所述:(P334 1) 1、将值类型的元素装箱为引用类型的元素,比如将一个Int32[]复制到一个ObjectI]。...(P336 3) 数组的传递和返回 Array.Copy:浅拷贝(对引用类型直接传递回引用对象)(P337 4) 创建下限非零的数组 推荐使用捏。...(P341 2) 1、允许访问堆上的托管数组对象的元素 2、允许访问非托管堆上的数组的元素 3、线程栈上的数组的元素(P342 last) 固定大小的数组 通常,由于数组是引用类型,所以结构定义的数组字段实际只是指向数组的指针或引用

76310

C#如何遍历ArrayList

大家好,又见面了,是你们的朋友全栈君。...(3)Count属性和Capacity属性 Count属性是目前ArrayList包含的元素的数量,这个属性是只读的。...InsertRange   这几个方法比较类似 Add方法用于添加一个元素到当前列表的末尾 AddRange方法用于添加一批元素到当前列表的末尾 Remove方法用于删除一个元素,通过元素本身的引用来删除...(6)ToArray方法   这个方法把ArrayList的元素Copy到一个新的数组。...(2)内部的Object类型的影响 对于一般的引用类型来说,这部分的影响不是很大,但是对于值类型来说,往ArrayList里面添加和修改元素,都会引起装箱和拆箱的操作,频繁的操作可能会影响一部分效率。

78820

.NET平台功能最强大,性能最佳的JSON库

用 $ref 表示重复和循环引用的序列化和反序列化。 目前唯一支持 ref 属性的 JSON 库。 支持几乎所有您常用的类型!并允许您自定义类型的行为。...允许使用 [RWField] 特性定制属性或字段的行为。 允许设置最大深度来限制内容大小。...其余类型将会被当作 Object,以 属性键/属性值 的形式映射。 Swifter.Json 安全吗? 每次发布之前都会观察至少一个月,期间会进行大量的测试,并且在实际项目中使用未发布的版本。...但即使这样,也无法保证它一定安全。所以,如果您发现了。 Bug 或某些不合理的地方请及时联系 QQ:1287905882,邮箱 1287905882@qq.com。...性能测试对比 图表的颜色随所用时间从 绿色 渐变为 黄色。当用时超过 3 倍时将以亮黄色显示。 Timeout: 表示用时过久。 Exception: 表示发生了异常。

20810

设计一个 .NET 可用的弱引用集合(可用来做缓存池使用)

虽然一般推荐这么设计,但是你可以使用本文所述的方法和代码作为按垃圾回收缓存的缓存池的设计。...---- 设计思路 既然现有 WeakReference 和 ConditionalWeakTable 可以帮助我们实现弱引用,那么我们可以考虑封装这两个类的任何一个或者两个来帮助我们完成弱引用集合...所以如果要根据 ConditionalWeakTable 来实现弱引用集合那么需要自己记录集合的所有的 Key,而这样的话我们依然需要自己实现一个用来记录所有 Key 的弱引用集合,相当于鸡生蛋蛋生鸡的问题...动手 弱引用集合我们需要这些使用场景: 向弱引用集合添加一个元素 此场景下仅仅修改集合而不需要读取任何状态。...向弱引用集合移除一个元素 既然可以在参数传入元素,说明此元素一定没有会垃圾回收;因此只要集合还存在此元素,一定可以确定地移除,不会出现不确定的状态。

13440
领券