第九章-泛型


1>介绍泛型的优点和缺点,尤其是:
● 性能
● 类型安全性
● 二进制代码重用
● 代码的扩展
● 命名约定
2>对值类型使用非泛型集合类,在把值类型转换为引用类型,和把引用类型转换为值类型时,需要进行装箱和拆箱操作。
注意:值类型存储在堆栈上,引用类型存储在堆上。 C#类是引用类型,结构是值类型。 
从值类型转换为引用类型称为装箱。如果方法需要把一个对象作为参数,而且传送了一个值类型,装箱操作就会自动进行。另一方面,装箱的值类型可以使用拆箱操作转换为值类型。在拆箱时,需要使用类型转换运算符。

1,例子显示了 System.Collections 命名空间中的 ArrayList 类。 ArrayList 存储对象,Add()方法定义为需要把一个对象作为参数,所以要装箱一个整数类型。在读取 ArrayList中的值时,要进行拆箱,把对象转换为整数类型。可以使用类型转换运算符把 ArrayList集合的第一个元素赋予变量 i1,在访问 int 类型的变量 i2 的 foreach 语句中,也要使用类型
转换运算符:

```
ArrayList list = new ArrayList();
list.Add(44);
int i1 = (int)list[0];
foreach (int i2 in list)
{
Console.WriteLine(i2);
}

```

System.Collections.Generic 命名空间中的 List<T>类不使用对象,而是在使用时定义类型。在下面的例子中, List<T>类的泛型类型定义为 int,所以 int 类型在 JIT 编译器动态生成的类中使用,不再进行装箱和拆箱操作:

```
List<int> list = new List<int>();
list.Add(44);
int i1 = list[0];
foreach (int i2 in list)
{
Console.WriteLine(i2);
}
```


3>命名约定
泛型类
型的命名规则:
● 泛型类型的名称用字母 T 作为前缀。
● 如果没有特殊的要求,泛型类型允许用任意类替代,且只使用了一个泛型类型,就可以用字符 T 作为泛型类型的名称

```
public class List<T> { }
public class LinkedList<T> { }
```

● 如果泛型类型有特定的要求(例如必须实现一个接口或派生于基类),或者使用了两个或多个泛型类型,就应给泛型类型使用描述性的名称:

```
public delegate void EventHandler<TEventArgs>(object sender, TEventArgs e);
public delegate TOutput Converter<TInput, TOutput>(TInput from);
public class SortedList<TKey, TValue> { }
```

1)创建泛型类
   在链表中,一个元素引用其后的下一个元素。所以必须创建一个类,将对象封装在链表中,引用下一个对象。类 LinkedListNode 包含一个对象 value,它用构造函数初始化,还可以用 Value 属性读取。另外, LinkedListNode 类包含对链表中下一个元素和上一个元素的引用,这些元素都可以从属性中访问.
  

```
public class LinkedListNode
{
private object value;
public LinkedListNode(object value)
{
this.value = value;
}
public object Value
{
get { return value; }
}
private LinkedListNode next;
public LinkedListNode Next
{
get { return next; }
internal set { next = value; }
}
private LinkedListNode prev;
public LinkedListNode Prev
{
get { return prev; }
internal set { prev = value; }
}
}
```

LinkedList 类包含 LinkedListNode 类型的 first 和 last 字段,它们分别标记了链表的头尾。 AddLast()方法在链表尾添加一个新元素。首先创建一个 LinkedListNode 类型的对象。如果链表是空的,则 first 和 last 字段就设置为该新元素;否则,就把新元素添加为链表中的最后一个元素。执行 GetEnumerator()方法时,可以用 foreach 语句迭代链表。 GetEnumerator()方法使用 yield 语句创建一个枚举器类型。

4>继承
(1)创建的 LinkedList<T>类执行了 IEnumerable<T>接口:

```
public class LinkedList<T> : IEnumerable<T>
{
//...
```

泛型类型可以执行泛型接口,也可以派生于一个类。泛型类可以派生于泛型基类:

```
public class Base<T>
{
}
public class Derived<T> : Base<T>
{
}
```

其要求是必须重复接口的泛型类型,或者必须指定基类的类型,如下所示:

```
public class Base<T>
{
}
public class Derived<T> : Base<string>
{
}
```

派生类可以是泛型类或非泛型类。例如,可以定义一个抽象的泛型基类,它在
派生类中用一个具体的类型实现。这允许对特定类型执行特殊的操作:

```
public abstract class Calc<T>
{
public abstract T Add(T x, T y);
public abstract T Sub(T x, T y);
}
public class SimpleCalc : Calc<int>
{
public override int Add(int x, int y)
{
return x + y;
}
public override int Sub(int x, int y)
{
return x - y;
}
}
```

5>静态成员
(1)泛型类的静态成员只能在类的一个实例中共享。下面看一个例子。 StaticDemo<T>类包含静态字段 x:

```
public class StaticDemo<T>
{
public static int x;
}
```

由于对一个 string 类型和一个 int 类型使用了 StaticDemo<T>类,所以存在两组静态字段:

```
StaticDemo<string>.x = 4;
StaticDemo<int>.x = 5;
Console.WriteLine(StaticDemo<string>.x);
```

6>泛型接口
(1)使用泛型可以定义接口,接口中的方法可以带泛型参数。在链表示例中,就执行了IEnumerable<T>接口,它定义了 GetEnumerator()方法,以返回
IEnumerator<T>

```
public interface IComparable<T>
{
int CompareTo(T other);
}
```

第 5 章中的非泛型接口 IComparable 需要一个对象, Person 类的 CompareTo()方法才能按姓氏给人员排序:

```

public class Person : IComparable
{
public int CompareTo(object obj)
{
Person other = obj as Person;
return this.lastname.CompareTo(other.lastname);
}
//...
```


7>泛型方法

除了定义泛型类之外,还可以定义泛型方法。在泛型方法中,泛型类型用方法声明来定义。
Swap<T>方法把 T 定义为泛型类型,用于两个参数和一个变量 temp:

```
void Swap<T>(ref T x, ref T y)
{
T temp;
temp = x;
x = y;
y = temp;
}
```

把泛型类型赋予方法调用,就可以调用泛型方法:

```
int i = 4;
int j = 5;
Swap<int>(ref i, ref j);
```

泛型方法可以像非泛型方法那样调用:

```
int i = 4;
int j = 5;
Swap(ref i, ref j);
```



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值