zoukankan      html  css  js  c++  java
  • 4.9 利用对应的泛型替换Hashtable[转]

     

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

    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类"主题。


    作者:水木    
     
  • 相关阅读:
    模板 素数筛选
    模板 BFS
    模板 01背包
    模板 计算1的个数
    模板 最长公共子序列
    模板 最长递增子序列
    模板 最长公共递增子序列
    zjuoj 3602 Count the Trees
    zjuoj 3608 Signal Detection
    zjuoj 3606 Lazy Salesgirl
  • 原文地址:https://www.cnblogs.com/hsapphire/p/1634760.html
Copyright © 2011-2022 走看看