`
pcajax
  • 浏览: 2163024 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

4.9 利用对应的泛型替换Hashtable[转]

阅读更多

 

 
  • 摘要:《C#3.0cookbook中文版》《C#3.0cookbook中文版》本书侧重于解决C#程序员在开发应用程序时遇到的各类问题,并以此组织全书内容。这些解决方案称为秘诀;每个秘诀都包含一个问题,他的解决方案及相关信息的讨论。 本节为大家介绍的是利用对应的泛型替换Hashtable。
  • 标签:泛型  C#3.0  0cookbook  C#3.0cookbook中文版
  • <script src="http://www.51cto.com/js/article/keywords_ad.js"></script>

4.9 利用对应的泛型替换Hashtable

问题

你希望通过用其泛型版本替换所有的Hashtable对象来增强应用程序的性能,并使得代码更容易处理。

解决方案

利用类型安全的泛型类System.Collections.Generic.Dictionary替换出现的所有System.Collections.Hashtable类。

下面给出了一个使用System.Collections.Hashtable对象的简单示例:

public static void UseNonGenericHashtable()
{
Console.WriteLine("\r\nUseNonGenericHashtable");
// Create and populate a Hashtable
Hashtable numbers = new Hashtable()
{ {1, "one"},"one"}, // Causes a boxing operation to occur for the key
{2, "two"} }; // Causes a boxing operation to occur for the key
// Display all key/value pairs in the Hashtable
// Causes an unboxing operation to occur on each iteration for the key
foreach (DictionaryEntry de in numbers)
{
Console.WriteLine("Key: " + de.Key + "\tValue: " + de.Value);
}
Console.WriteLine(numbers.IsReadOnly);
Console.WriteLine(numbers.IsFixedSize);
Console.WriteLine(numbers.IsSynchronized);
Console.WriteLine(numbers.SyncRoot);
numbers.Clear();
}
下面给出了使用System.Collections.Generic.Dictionary<T,U>对象的相同代码:
public static void UseGenericDictionary()
{
Console.WriteLine("\r\nUseGenericDictionary");
// Create and populate a Dictionary
Dictionary<int, string> numbers = new Dictionary<int, string>()
{ { 1, "one" }, { 2, "two" } };
// Display all key/value pairs in the Dictionary
foreach (KeyValuePair<int, string> kvp in numbers)
{
Console.WriteLine("Key: " + kvp.Key + "\tValue: " + kvp.Value);
}
Console.WriteLine(((IDictionary)numbers).IsReadOnly);
Console.WriteLine(((IDictionary)numbers).IsFixedSize);
Console.WriteLine(((IDictionary)numbers).IsSynchronized);
Console.WriteLine(((IDictionary)numbers).SyncRoot);
numbers.Clear();
}

讨论

对于应用程序中Hashtable的简单实现,这种替换应该相当容易。不过,有一些事情要注意。例如,泛型类Dictionary没有实现ICloneable接口,而Hashtable类则实现了该接口。

表4-3显示了两个类中同时实现的等价成员。

表4-3:Hashtable和泛型类Dictionary中的等价成员

Hashtable类中的成员 泛型类Dictionary中的等价成员
Comparer属性
Count属性 Count属性
IsFixedSize属性 ((IDictionary)myDict).IsFixedSize
IsReadOnly属性 ((IDictionary)myDict).IsReadOnly
IsSynchronized属性 ((IDictionary)myDict).IsSynchronized
Item属性 Item属性
Keys属性 Keys属性
SyncRoot属性 ((IDictionary)myDict).SyncRoot
Values属性 Values属性
Add方法 Add方法
Clear方法 Clear方法
Clone方法 使用重载的构造函数,它接受一个IDictionary<T,U>类型
Contains方法 ContainsKey方法
ContainsKey方法 ContainsKey方法
ContainsValue方法 ContainsValue方法
CopyTo方法 ((ICollection)myDict).CopyTo(arr,0)

表4-3:Hashtable和泛型类Dictionary中的等价成员(续)

Hashtable类中的成员 泛型类Dictionary中的等价成员
Remove方法 Remove方法
Synchronized静态方法 lock(myDictionary.SyncRoot) {...}
 TryGetValue方法
在表4-3中,有些情况下在Hashtable的成员与泛型类Dictionary的成员之间没有一对一的关系。从属性开始,注意只有Count、Keys、Values和Item这些属性同时存在于两个类中。为了弥补Dictionary类中缺失的属性,可以强制转换到IDictionary。下面的代码显示了如何使用这些强制转换获得缺失的属性:
    Dictionary<int, string> numbers = new Dictionary<int, string>(); 
Console.WriteLine(((IDictionary)numbers).IsReadOnly);
Console.WriteLine(((IDictionary)numbers).IsFixedSize);
Console.WriteLine(((IDictionary)numbers).IsSynchronized);
Console.WriteLine(((IDictionary)numbers).SyncRoot);

注意: 由于没有代码能够返回泛型Dictionary的同步版本,IsSynchronized属性将总是返回false。SyncRoot属性将总是返回调用它的相同对象。实质上,这个属性返回this指针。Microsoft决定取消从任何泛型集合类创建同步包装器的能力。

作为替代,他们建议使用lock关键字来锁定整个集合或者适合你的需要的另一类同步对象。

由于泛型类Dictionary中也缺失Clone方法(这是由于这个类没有实现ICloneable接口),可以代之以使用重载的构造函数,它接受一个IDictionary<T,U>类型:

    // Create and populate a Dictionary
Dictionary<int, string> numbers = new Dictionary<int, string>()
{ { 1, "one" }, { 2, "two" } };
// Display all key/value pairs in the original Dictionary.
foreach (KeyValuePair<int, string> kvp in numbers)
{
Console.WriteLine("Original Key: " + kvp.Key + "\tValue: " + kvp.Value);
}
// Clone the Dictionary object.
Dictionary<int, string> clonedNumbers = new Dictionary<int, string>(numbers);
// Display all key/value pairs in the cloned Dictionary.
foreach (KeyValuePair<int, string> kvp in numbers)
{
Console.WriteLine("Cloned Key: " + kvp.Key + "\tValue: " + kvp.Value);
}
Dictionary类中还缺失了另外两个方法:Contains和CopyTo方法。可以很容易地在Dictionary类中复制Contains方法。在Hashtable类中,Contains方法和ContainsKey方法都会展示相同的行为;因此,可以简单地使用Dictionary类的ContainsKey方法来模拟Hashtable类的Contains方法:
    // Create and populate a Dictionary
Dictionary<int, string> numbers =
new Dictionary<int, string>()
{ { 1, "one" }, { 2, "two" } };
Console.WriteLine("numbers.ContainsKey(1) == " + numbers.ContainsKey(1));
Console.WriteLine("numbers.ContainsKey(3) == " + numbers.ContainsKey(3));
在Dictionary类中也很容易模拟CopyTo方法,但是它需要做更多一点的工作:
    // Create and populate a Dictionary
Dictionary<int, string> numbers =
new Dictionary<int, string>()
{ { 1, "one" }, { 2, "two" } };
// Display all key/value pairs in the Dictionary.
foreach (KeyValuePair<int, string> kvp in numbers)
{
Console.WriteLine("Key: " + kvp.Key + "\tValue: " + kvp.Value);
}
// Create object array to hold copied information from Dictionary object.
KeyValuePair<int, string>[] objs = new KeyValuePair<int, string>[numbers.Count];
// Calling CopyTo on a Dictionary
// Copies all KeyValuePair objects in Dictionary object to objs[]
((IDictionary)numbers).CopyTo(objs, 0);
// Display all key/value pairs in the objs[].
foreach (KeyValuePair<int, string> kvp in objs)
{
Console.WriteLine("Key: " + kvp.Key + "\tValue: " + kvp.Value);
}

对Dictionary对象调用CopyTo方法涉及建立一个KeyValuePair<T,U>对象的数组,在调用CopyTo方法之后,该数组最终将用于保存Dictionary对象内的所有KeyValuePair<T,U>对象。接下来,将Dictionary对象numbers强制转换成IDictionary类型,以便可以调用CopyTo方法。一旦调用了CopyTo方法,objs数组将包含原始numbers对象中的所有KeyValuePair<T,U>对象的副本。注意:使用foreach循环以与numbers对象相同的方式迭代objs数组。

参考

MSDN文档中的"System.Collections.Hashtable类"和"System.Collections.Generic. Dictionary类"主题。

分享到:
评论

相关推荐

    java Hashtable的泛型化

    3. **自动装箱与拆箱**:对于基本类型对应的包装类,泛型`Hashtable`支持自动装箱(如`Integer`与`int`之间)和拆箱,简化了代码。 4. **可读性**:通过明确指定类型,代码的意图更加清晰,阅读和维护起来更容易。 ...

    C# 工具类 泛型转JSON(Newtonsoft.Json)

    C# 工具类 泛型转JSON 使用 Newtonsoft.Json 转换JSON

    C# json 转hashtable

    标题"**C# json 转 hashtable**"涉及到的主要知识点是将JSON字符串解析成`Hashtable`对象,这个过程通常称为反序列化。在C#中,我们可以使用`System.Web.Script.Serialization`或`Newtonsoft.Json`库来实现这一转换...

    泛型类型转换Demo

    在Java编程语言中,泛型是...通过"泛型类型转换Demo",我们可以学习到如何在实际项目中有效地利用泛型进行类型安全的编程,以及如何处理各种泛型相关的转换和操作。熟练掌握这些知识将有助于提高代码的质量和可维护性。

    里氏替换原则+排序_接口_泛型比较器+序列化+泛型集合.rar

    简单介绍 里氏替换原则 简单工程模式 实现任意排序 使用了 is 和 as 方法 ArrayList数组 与 List泛型集合 Hashtable数组 与 Dictionary,v&gt;泛型集合 的基本使用 序列化 将数据存储

    C#【泛型】实现的【通用】结构体转字节数组

    C#【泛型】实现的【通用】结构体转字节数组,包含网上收集的网页参考资料、非通用的【StructTest】工程、泛型实现的通用【Struct2BytesGenericType】工程。 VS2010编译运行。

    json字符串转化为list泛型

    在Java编程中,我们经常需要将JSON格式的数据转换为Java对象,这通常涉及到将JSON字符串转化为List泛型。JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和...

    Java泛型学习【转自百度百科】

    1. 类型参数(Type Parameter):泛型中的"T"、"E"、"K"、"V"等是类型参数的占位符,它们代表某种未知的类型,在实际使用时会被具体的类型替换。 2. 泛型类(Generic Class):在类定义中使用类型参数,如`public ...

    抽象工厂 SQL 和Access 利用泛型读取表中数据 WCF发布出去

    在"利用泛型读取表中数据"的情境下,开发人员可能定义了一个泛型类或方法,可以处理任何类型的数据,无论是整数、字符串还是自定义对象。这样做使得代码更灵活,能适应多种数据类型,同时减少类型转换的必要。 WCF...

    DataReader反射泛型实体对象

    使用反射和泛型,我们可以编写一个通用方法,接收`DataReader`和类型信息作为参数,然后逐行读取数据,利用反射实例化指定类型的对象并设置属性值。 示例代码可能如下: ```csharp public static T ...

    JAVA5泛型和反射

    例如,使用泛型的 `Hashtable` 可以声明为 `Hashtable, Value&gt;`,其中 `Key` 和 `Value` 是类型参数,表示键和值的具体类型。这样,当向泛型 `Hashtable` 添加或取出元素时,编译器会检查类型是否匹配,无需显式的...

    c# 利用泛型解析xml文件

    当我们谈论“利用泛型解析XML文件”时,我们实际上是在讨论如何使用C#的泛型类和方法来处理XML数据。XML是一种常用的数据交换格式,用于存储和传输结构化数据。下面我们将详细探讨如何实现这个过程。 首先,我们...

    利用反射生成泛型类对象

    反射和泛型是一种重要的解决途径。 此代码是一个生成泛型对象的类。 比如: Pool&lt;Point&gt; pool = new Pool(){}; Point p = pool.get(x, y); //在此构造Point对象 ... pool.put(p); 希望能帮助那些为查找泛型构造器、...

    泛型工具类

    ### 泛型工具类在IT行业的应用与理解 在现代软件开发中,泛型作为一种强大的类型安全机制,被广泛应用于各种编程语言中,尤其是Java。泛型允许开发者编写灵活且可重用的代码,同时避免了运行时类型检查错误。在Java...

    C#泛型类、泛型方法、泛型接口、泛型委托的实例

    本文将深入探讨泛型类、泛型方法、泛型接口和泛型委托,并通过实例来阐述它们的应用。 首先,我们来看泛型类。泛型类是具有一个或多个类型参数的类。类型参数是在定义类时使用的占位符,实际的类型在创建类的实例时...

    Dictionary泛型的使用,带有例子

    泛型Dictionary和HashTable都是用于存储键值对的集合,但它们有以下几个区别: * 泛型Dictionary对添加的元素具有类型约束,HashTable可以添加任意类型的元素。 * 泛型Dictionary不需要装箱、拆箱操作,HashTable...

    泛型java的泛型知识,非常有用

    在泛型之前,我们需要手动进行类型转换,如 `Hashtable` 的使用。引入泛型后,如 `List&lt;String&gt;` 直接存储和获取 `String` 对象,无需显式转换,增强了代码的可读性和安全性。 5. **类型擦除** - Java 泛型在编译...

    Json与实体相互转换,支持IList泛型

    Json转换为实体;Json转换为IList;实体转换为Json;IList转换为Json;

    泛型dao 泛型dao 泛型dao

    Struts2、Hibernate、Spring整合的泛型DAO (本人评价: 代码开发效率提高30% 代码出错率减少70%) 对于大多数开发人员,系统中的每个 DAO 编写几乎相同的代码到目前为止已经成为一种习惯。虽然所有人都将这种重复...

Global site tag (gtag.js) - Google Analytics