在本文中,我们将给您介绍关于c#–IDictionary和IReadOnlyDictionary的扩展方法的详细内容,并且为您解答c#dictionarykey的相关问题,此外,我们还将为您提供关于.
在本文中,我们将给您介绍关于c# – IDictionary和IReadOnlyDictionary的扩展方法的详细内容,并且为您解答c#dictionary key的相关问题,此外,我们还将为您提供关于.net Redis分布式锁,Dictionary,ConcurrentDictionary 介绍、C# Dictionary和SortedDictionary的简介、c# – DictionaryBase和Dictionary之间的差异、c# – StringDictionary类和Dictionary 之间有区别吗的知识。
本文目录一览:- c# – IDictionary和IReadOnlyDictionary的扩展方法(c#dictionary key)
- .net Redis分布式锁,Dictionary,ConcurrentDictionary 介绍
- C# Dictionary和SortedDictionary的简介
- c# – DictionaryBase和Dictionary之间的差异
- c# – StringDictionary类和Dictionary 之间有区别吗
c# – IDictionary和IReadOnlyDictionary的扩展方法(c#dictionary key)
好吧,我想为IDictionary和IReadOnlyDictionary接口编写一个扩展方法:
public static TValue? GetNullable<TKey,TValue>(this IReadOnlyDictionary<TKey,TValue> dictionary,TKey key) where TValue : struct { return dictionary.ContainsKey(key) ? (TValue?)dictionary[key] : null; } public static TValue? GetNullable<TKey,TValue>(this IDictionary<TKey,TKey key) where TValue : struct { return dictionary.ContainsKey(key) ? (TValue?)dictionary[key] : null; }
但是当我将它用于实现两个接口的类(例如Dictionary< Tkey,TValue>)时,我得到了“模糊的调用”.我不想输入var value = myDic.GetNullable< IReadOnlyDictionary< MyKeyType,MyValueType>>(key),我希望它只是var value = myDic.GetNullable(key).
这可能吗?
解决方法
public static TValue? GetNullableKey<TKey,TValue>(this IEnumerable<keyvaluePair<TKey,TValue>> dictionary,TKey,key) where TValue : struct { // Your code here. // Per @nmclean: to reap performance benefits of dictionary lookup,try to cast // dictionary to the expected dictionary type,e.g. IDictionary<K,V> or // IReadOnlyDictionary<K,V>. Thanks for that nmclean! }
IDictionary< TKey,TValue>和IReadOnlyDictionary< TKey,TValue>继承自IEnumerable< keyvaluePair< TKey,TValue>>.
HTH.
更新:回答您的评论问题
如果你不需要调用只出现在一个接口或另一个接口上的方法(即你只调用IEnumerable< keyvaluePair< TKey,TValue>>)上存在的方法,那么不,你不需要那个码.
如果你确实需要在IDictionary< TKey,TValue>上调用方法.或IReadOnlyDictionary< TKey,TValue>在公共基础接口上不存在的接口,然后是,您需要查看您的对象是否是其中一个,以了解哪些方法可以被调用.
更新:您可能(很可能)不应该使用此解决方案
因此,从技术上讲,这个解决方案在回答OP的问题时是正确的,如上所述.然而,这真的不是一个好主意,正如其他人在下面评论过的那样,并且我已经承认这些评论是正确的.
首先,字典/地图的整个点是O(1)(恒定时间)查找.通过使用上面的解决方案,您现在已将O(1)操作转换为O(n)(线性时间)操作.如果你的词典中有1,000,000个项目,那么查找关键值需要多达100万次(如果你真的不走运).这可能会对性能产生重大影响.
一本小字典怎么样?那么问题就变成了,你真的需要一本字典吗?列表会更好吗?或许是一个更好的问题:你在哪里开始注意到使用O(n)而不是O(1)查找的性能影响以及你期望执行这样的查找的频率是多少?
最后,OP的情况是一个实现IReadOnlyDictionary< TKey,TValue>的对象.和IDictionary< TKey,TValue>是,奇怪,作为IDictionary< TKey,TValue>的行为是IReadOnlyDictionary< TKey,TValue>行为的超集.和标准词典< TKey,TValue> class已经实现了这两个接口.因此,如果OP(我假设,专门)类型继承自Dictionary< TKey,TValue>相反,当需要只读功能时,类型可以简单地转换为IReadOnlyDictionary< TKey,TValue>,可能完全避免这个问题.即使问题不是不可避免的(例如,在某个地方,对其中一个接口进行了转换),实现两个扩展方法仍然会更好,每个接口一个.
我想在完成这个主题之前还需要一个程序问题.铸造字典< TKey,TValue>到IReadOnlyDictionary< TKey,TValue>只确保接收到铸造值的任何东西本身都不能改变底层集合.但是,这并不意味着对创建转换引用的字典实例的其他引用不会改变底层集合.这是IReadOnly *集合接口背后的抱怨之一 – 这些接口引用的集合可能不是真正的“只读”(或者,通常是暗示的,不可变的)集合,它们只是通过特定的引用来防止集合的变异(尽管有一个具体的ReadOnly *类的实际实例).这是(以及其他)创建集合类的System.Collections.Immutable命名空间的一个原因.此命名空间中的集合表示真正不可变的集合.这些集合的“突变”导致返回由突变状态组成的全新集合,使原始集合不受影响.
.net Redis分布式锁,Dictionary,ConcurrentDictionary 介绍
1、背景
在计算机世界里,对于锁大家并不陌生,在现代所有的语言中几乎都提供了语言级别锁的实现,为什么我们的程序有时候会这么依赖锁呢?这个问题还是要从计算机的发展说起,随着计算机硬件的不断升级,多核cpu,多线程,多通道等技术把计算机的计算速度大幅度提升,原来同一时间只能执行一条cpu指令的时代已经过去。随着多条cpu指令可以并行执行的原因,原来不曾出现的资源竞争随着出现,在程序中的体现就是随处可见的多线程环境。比如要更新数据库的一个信息,如果没有并发控制,多个线程同时操作的话,就会出现互相覆盖的现象发生。
锁要解决的就是资源竞争的问题,也就是要把执行的指令顺序化。
在互联网背景下,电商行业是普遍都是多线程执行,并发量大。比如下单秒杀抢购商品活动,属于高并发情况,库存的保证就尤其重要了,不能出现超卖现象。程序员所要做的事情就是需要单线程执行获取库存,再减库存操作,保证数据原子性。
在多台服务器中,锁就是重点。
2、应用
我们先来介绍下单线程下的情况,假设有个商品A,库存500件,假设每次购买1件,单价1元,这样就只有是500次下单时成功的,其他都不能下单。
2.1 Store商品存储-Dictionary
数据库不存在的情况下,用Dictionary来代替
创建了Store后,主程序创建下单,单线程执行。
执行结果:
执行正常,4人不能下单。
改成多线程执行,直接出现超卖现象,其中用Task.Run 模拟多线程,其中Order(int i) i变量注意,不能直接填写i,异步中上下文不存在,因为主线程以及跑完了,再运行异步Task线程,这时变量已是最后一个被覆盖。
解决方案是重复赋值变量替换
结果:
500多的人都买了。
解决方案:
2.1.1 lock 加锁
lock很明显影响性能。
执行结果:
正常。
2.1.2 使用ConcurrentDictionary
ConcurrentDictionary 本身是线程安全的,源代码就是加了lock
执行结果符合。
2.2 用Redis分布式锁
redis是单线程运行,所以适合。原理也很简单,运用redis以下指令
1、SETNX
SETNX key val:当且仅当key不存在时,set一个key为val的字符串,返回1;若key存在,则什么都不做,返回0。
2、expire
expire key timeout:为key设置一个超时时间,单位为second,超过这个时间锁会自动释放,避免死锁。
3、delete
delete key:删除key
在使用Redis实现分布式锁的时候,主要就会使用到这三个命令。
原理如下:
1、先获取redis锁,设置一个随机字符串
执行了805次,看下输出最后数量有没有小于0
结果显示0,正确,没超卖
C# Dictionary和SortedDictionary的简介
1、SortedDictionary 泛型类
SortedDictionary 泛型类是检索运算复杂度为 O(log n) 的二叉搜索树,其中 n 是字典中的元素数。就这一点而言,它与 SortedList
泛型类相似。这两个类具有相似的对象模型,并且都具有 O(log n) 的检索运算复杂度。这两个类的区别在于内存的使用以及插入和移除元素的速度:
- SortedList 使用的内存比 SortedDictionary 少。
- SortedDictionary 可对未排序的数据执行更快的插入和移除操作:它的时间复杂度为 O(log n),而SortedList 为 O(n)。
- 如果使用排序数据一次性填充列表,则 SortedList 比 SortedDictionary 快。
每个键/值对都可以作为 KeyValuePair
结构进行检索,或作为 DictionaryEntry
通过非泛型 IDictionary
接口进行检索。
只要键用作 SortedDictionary 中的键,它们就必须是不可变的。SortedDictionary 中的每个键必须是唯一的。键不能为空引用(在 Visual Basic 中为 Nothing),但是如果值类型 TValue 为引用类型,该值则可以为空。
SortedDictionary 需要比较器实现来执行键比较。可以使用一个接受 comparer 参数的构造函数来指定IComparer
泛型接口的实现;如果不指定实现,则使用默认的泛型比较器 Comparer.Default
。如果类型 TKey实现 System.IComparable
泛型接口,则默认比较器使用该实现。
C# 语言的 foreach 语句,需要集合中每个元素的类型。由于 SortedDictionary 的每个元素都是一个键/值对,因此元素类型既不是键的类型,也不是值的类型。而是 KeyValuePair 类型
2、要使用Dictionary集合,需要导入C#泛型命名空间
System.Collections.Generic
(程序集:mscorlib)
3、Dictionary的描述
- 从一组键(Key)到一组值(Value)的映射,每一个添加项都是由一个值及其相关连的键组成
- 任何键都必须是唯一的
- 键不能为空引用null(VB中的Nothing),若值为引用类型,则可以为空值
- Key和Value可以是任何类型(string,int,custom class 等)
4、Dictionary常用用法:以 key 的类型为 int , value的类型为string 为例
1.创建及初始化
Dictionary<int,string>myDictionary=newDictionary<int,string>();
2.添加元素
myDictionary.Add(1,"C#");
3.通过Key查找元素
if(myDictionary.ContainsKey(1)) { Console.WriteLine("Key:{0},Value:{1}","1", myDictionary[1]); }
4.通过KeyValuePair遍历元素
foreach(KeyValuePair<int,string>kvp in myDictionary) ...{ Console.WriteLine("Key = {0}, Value = {1}",kvp.Key, kvp.Value); }
5.仅遍历键 Keys 属性
Dictionary<int,string>.KeyCollection keyCol=myDictionary.Keys; foreach(intkeyinkeyCol) ...{ Console.WriteLine("Key = {0}", key); }
6.仅遍历值 Valus属性
Dictionary<int,string>.ValueCollection valueCol=myDictionary.Values; foreach(stringvalueinvalueCol) ...{ Console.WriteLine("Value = {0}", value); }
7.通过Remove方法移除指定的键值
myDictionary.Remove(1); if(myDictionary.ContainsKey(1)) ...{ Console.WriteLine("Key:{0},Value:{1}","1", myDictionary[1]); } else { Console.WriteLine("不存在 Key : 1"); }
5、其它常见属性和方法的说明:
Comparer: 获取用于确定字典中的键是否相等的 IEqualityComparer。
Count: 获取包含在 Dictionary中的键/值对的数目。
Item: 获取或设置与指定的键相关联的值。
Keys: 获取包含 Dictionary中的键的集合。
Values: 获取包含 Dictionary中的值的集合。
Add: 将指定的键和值添加到字典中。
Clear: 从 Dictionary中移除所有的键和值。
ContainsKey: 确定 Dictionary是否包含指定的键。
ContainsValue: 确定 Dictionary是否包含特定值。
GetEnumerator: 返回循环访问 Dictionary的枚举数。
GetType: 获取当前实例的 Type。 (从 Object 继承。)
Remove: 从 Dictionary中移除所指定的键的值。
ToString: 返回表示当前 Object的 String。 (从 Object 继承。)
TryGetValue: 获取与指定的键相关联的值。
使用for循环遍历键值
Dictionary<string, int> Dict = new Dictionary<string, int>(); Dict .Add( "a", 1 ); Dict .Add( "b", 2 ); Dict .Add( "c", 3 ); Dict .Add( "d", 4 ); Dict .Add( "e", 5 ); Dict .Add( "f", 6 ); for(int i = 0 ; i < DicTest.Count ; i++) { Debug.Log(DicTest.ToList()[i].Key + ":" + DicTest.ToList()[i].Value); }
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对的支持。如果你想了解更多相关内容请查看下面相关链接
- C#中Dictionary泛型集合7种常见的用法
- C#针对xml文件转化Dictionary的方法
- C#中Dictionary的作用及用法讲解
- C#中查找Dictionary中重复值的方法
- C# Hashtable/Dictionary写入和读取对比详解
- C#中Dictionary几种遍历的实现代码
- c# 遍历 Dictionary的四种方式
- C#存储相同键多个值的Dictionary实例详解
- C#数组中List, Dictionary的相互转换问题
- 分析C# Dictionary的实现原理
c# – DictionaryBase和Dictionary之间的差异
这两个课程几乎相同!
任何形式的帮助将不胜感激
谢谢
解决方法
我认为这会更有帮助When to use generics?
Using generic collections is generally recommended,because you gain
the immediate benefit of type safety without having to derive from a
base collection type and implement type-specific members. Generic
collection types also generally perform better than the corresponding
nongeneric collection types (and better than types that are derived
from nongeneric base collection types) when the collection elements
are value types,because with generics there is no need to Box the
elements.
也是经过,Introduction to Generics
Generic classes and methods combine reusability,type safety and efficiency in a way that their non-generic counterparts cannot. Generics are most frequently used with collections and the methods that operate on them. Version 2.0 of the .NET Framework class library provides a new namespace,System.Collections.Generic,which contains several new generic-based collection classes. It is recommended that all applications that target the .NET Framework 2.0 and later use the new generic collection classes instead of the older non-generic counterparts
c# – StringDictionary类和Dictionary 之间有区别吗
System.Collections.Specialized包含StringDictionary
http://msdn.microsoft.com/en-us/library/system.collections.specialized.stringdictionary.aspx#Y1626
泛型中强类型字典有什么区别?
解决方法
因此,与Dictionary< String,String>不同,它不实现任何通用接口,因此它不能与LINQ一起使用(除非您使用Cast())
此外,StringDictionary将所有键标准化为小写.(为了使不区分大小写的字典< String,String>,传递StringComparer.OrdinalIgnoreCase;这也更容易与土耳其兼容)
关于c# – IDictionary和IReadOnlyDictionary的扩展方法和c#dictionary key的问题我们已经讲解完毕,感谢您的阅读,如果还想了解更多关于.net Redis分布式锁,Dictionary,ConcurrentDictionary 介绍、C# Dictionary和SortedDictionary的简介、c# – DictionaryBase和Dictionary之间的差异、c# – StringDictionary类和Dictionary 之间有区别吗等相关内容,可以在本站寻找。
本文标签: