C#泛型秘诀(7)

4.11 在泛型字典类中使用foreach

问题

您希望在实现了System. Collections.Generic.IDictionary接口的类型枚举元素,如System.Collections.Generic.Dictionary 或 System.Collections.Generic.SortedList。

解决方案

最简单的方法是在foreach循环中使用KeyValuePair结构体:

// 创建字典对象并填充.
  Dictionary<int, string> myStringDict = new Dictionary<int, string>();
  myStringDict.Add(1, "Foo");
  myStringDict.Add(2, "Bar");
  myStringDict.Add(3, "Baz");
  // 枚举并显示所有的键/值对.
  foreach (KeyValuePair<int, string> kvp in myStringDict)
  {
    Console.WriteLine("key  " + kvp.Key);
    Console.WriteLine("Value " + kvp.Value);
}

讨论

非泛型类System.Collections.Hashtable (对应的泛型版本为System.Collections.Generic.Dictionary class), System.Collections.CollectionBase和System.Collections.SortedList 类支持在foreach使用DictionaryEntry类型:

foreach (DictionaryEntry de in myDict)
  {
    Console.WriteLine("key " + de.Key);
    Console.WriteLine("Value " + de.Value);
}

但是Dictionary对象支持在foreach循环中使用KeyValuePair<T,U>类型。这是因为GetEnumerator方法返回一个Ienumerator,而它依次返回KeyValuePair<T,U>类型,而不是DictionaryEntry类型。

KeyValuePair<T,U>类型非常合适在foreach循环中枚举泛型Dictionary类。DictionaryEntry类型包含的是键和值的object对象,而KeyValuePair<T,U>类型包含的是键和值在创建一个Dictionary对象是被定义的原本类型。这提高了性能并减少了代码量,因为您不再需要把键和值转化为它们原来的类型。

阅读参考

查看MSDN文档中的“System.Collections.Generic.Dictionary Class”、“System.Collections.Generic. SortedList Class”和“System.Collections.Generic.KeyValuePair Structure”主题。

4.12类型参数的约束

问题

您希望创建泛型类型时,它的类型参数支持指定接口,如IDisposable。

解决方案

使用约束强制泛型的类型参数实现一个或多个指定接口:

public class DisposableList<T> : IList<T>
    where T : IDisposable
  {
    private List<T> _items = new List<T>();
    // 用于释放列表中的项目的私有方法
    private void Delete(T item)
    {
      item.Dispose();
    }
}

时间: 2025-01-19 11:56:25

C#泛型秘诀(7)的相关文章

C#泛型秘诀(8完)

4.13 初始化泛型变量为它们的默认值 问题 您的泛型类包含一个变量,它的类型和类中定义的类型参数一样.在构造泛型类时,您希望这个变量被初始化为它的默认值. 解决方案 简单地使用default关键字把变量初始化为它的默认值: public class DefaultValueExample<T> { T data = default(T); public bool IsDefaultData() { T temp = default(T); if (temp.Equals(data)) { r

C#泛型秘诀(2)

4.3 获取泛型的类型 问题 您需要在运行时获得一个泛型类型实例的Type对象. 解决方案 在使用typeof操作符时提供类型参数:使用类型参数实例化的泛型类型,用GetType()方法. 声明一个一般类型和一个泛型类型如下: public class Simple { public Simple() { } } public class SimpleGeneric<T> { public SimpleGeneric() { } } 使用typeof操作符和简单类型的名称就可以在运行时获得简单

C#泛型秘诀(1)

4.0 介绍 泛型,一个期待已久的功能,随着C# 2.0版本编译器的到来最终出现.泛型是一个非常有用的功能,它使得您的代码变得精简而富有效率.这些将在秘诀4.1进行详细讲述.泛型的到来使得您可以编写更为强大的应用程序,但这需要正确地使用它.如果您考虑把ArrayList,Queue,Stack和Hashtable对象转变为使用相应的泛型版本,可以阅读秘诀4.4,4.5和4.10.当您阅读过后,会发现这种转变不一定简单,甚至有可能会不再打算进行转变. 本章的另外一些秘诀涉及到.NET Framew

C#泛型秘诀(6)

4.9 使用泛型创建只读集合 问题 您希望类中的一个集合里的信息可以被外界访问,但不希望用户改变这个集合. 解决方案 使用ReadOnlyCollection<T>包装就很容易实现只读的集合类.例子如,Lottery类包含了中奖号码,它可以被访问,但不允许被改变: public class Lottery { // 创建一个列表. List<int> _numbers = null; public Lottery() { // 初始化内部列表 _numbers = new List

C#泛型秘诀(5.1)

4.8 反转Sorted List里的内容 问题 您希望在数组和列表类型中可以反转sorted list里的内容同时又维持SortedList和SortedList<T>类原来的功能.无论是SortedList还是泛型SortedList<T>类都直接提供了完成这个功能的方法而又不需要重填列表. 解决方案 ReversibleSortedList<TKey, TValue>类提供了这些功能,它基于SortedList<TKey, TValue>类,所以拥有相

C#泛型秘诀(4)

4.6 链表的实现 问题 您需要链表数据结构,这样就可以很容易地添加和删除元素. 解决方案 使用泛型LinkedList<T>类.下面的方法创建了一个LinkedList<T>类,并往链表对象中添加节点,然后使用了几种方法从链表节点中获得信息. public static void UseLinkedList() { // 创建一个LinkedList 对象. LinkedList<TodoItem> todoList = new LinkedList<TodoI

C#泛型秘诀(3)

4.5 使用相应的泛型版本替换Stack和Queue 问题 您希望通过将所有Stack和Queue对象替换为相应的泛型版本以提高应用程序的效率,并使得代码更易于使用.当结构体或其他值类型存储在这些数据结构中时,会导致装箱/拆箱操作,这时就需要这么做. 解决方案 使用System.Collections.Generic.Stack和System.Collections.Generic.Queue对象来替换现有的System.Collections.Stack和System.Collections.

C#泛型秘诀(5.3)

Nested Types#region Nested Types Enumerator K, V#region Enumerator <K, V> [Serializable, StructLayout(LayoutKind.Sequential)] private struct Enumerator<K, V> : IEnumerator<KeyValuePair<K, V>>, IDisposable, IDictionaryEnumerator, IE

C#泛型秘诀(5.2)

私有方法#region 私有方法 private void EnsureCapacity(int min) { int num1 = (this.keys.Length == 0) ? 4 : (this.keys.Length * 2); if (num1 < min) { num1 = min; } this.InternalSetCapacity(num1, false); } //返回指定索引的值 private TValue GetByIndex(int index) { if ((i