C#泛型类用法详解(附带实例)
C# 中,泛型类的定义如下:
如果有两个泛型数据类型,则此类的定义如下:
例如,有一个泛型类与对象的程序如下所示:
【实例 1】定义泛型类,设定整数然后输出,读者可以从程序认识整个泛型的流程。
有时候在设计程序时,程序设计师喜欢用下列方式设计第 8 行:
上述是 Microsoft 公司建议的:需要声明的 db 字段可以为 Null,这可以让程序有比较大的弹性,整个设计可以参考下面的实例,这对程序执行结果没有影响。
【实例 2】泛型类主要可以用于处理不同类型的数据,本实例是定义泛型类,设定整型与字符串型数据然后输出。
【实例 3】使用属性概念重新设计实例 2。
【实例 4】使用泛型创建字典类型的数据。
有的 C# 程序设计师会在第 1~3 行(或第 3~8 行)声明与创建类对象 noodle(dict)时,采用以下编码方式:
【实例 5】声明含数组字段的泛型类,设定数组元素和输出。
【实例 6】扩充设计实例 5,增加字符串型数据做测试,同时输出索引值对照。
【实例 7】在泛型类内使用泛型方法 AddItem(),创建泛型数组 arr[ ]。
【实例 8】更新实例 7,创建泛型数组时,第 1 个参数是索引,第 2 个参数是泛型。
【实例 9】设定泛型方法回传数据为泛型。
【实例 10】重新设计实例 9,增加测试输出超出泛型索引的结果,同时设定泛型的类型增加?,这是为了可能有 Null 的参数回传。
存取修饰词 class 泛型名称<T> { // 字段、属性和方法 }
如果有两个泛型数据类型,则此类的定义如下:
存取修饰词 class 泛型名称<T, U> { // 字段、属性和方法 }
C#泛型类中的字段
最简单的泛型类,假设只有一个类型参数是定义字段,定义如下:存取修饰词 class 泛型名称<T> { 存取修饰词 T 域名; }
例如,有一个泛型类与对象的程序如下所示:
DataBank<int> x = new DataBank<int>(); ... public class DataBank<T> { public T db; }在程序编译阶段,泛型 T 将会被 int 替换,这时 db 字段将是整型变量 db。
【实例 1】定义泛型类,设定整数然后输出,读者可以从程序认识整个泛型的流程。
DataBank<int> x = new DataBank<int>(); x.db = 5; Console.WriteLine($"x = {x.db}"); public class DataBank<T> { public T db; }执行结果
x = 5
有时候在设计程序时,程序设计师喜欢用下列方式设计第 8 行:
public T? db;
上述是 Microsoft 公司建议的:需要声明的 db 字段可以为 Null,这可以让程序有比较大的弹性,整个设计可以参考下面的实例,这对程序执行结果没有影响。
DataBank<int> x = new DataBank<int>(); x.db = 5; Console.WriteLine($"x = {x.db}"); public class DataBank<T> { public T? db; }
【实例 2】泛型类主要可以用于处理不同类型的数据,本实例是定义泛型类,设定整型与字符串型数据然后输出。
DataBank<int> x = new DataBank<int>(); x.db = 5; Console.WriteLine($"x = {x.db}"); DataBank<string> str = new DataBank<string>(); str.db = "C#"; Console.WriteLine($"str = {str.db}"); public class DataBank<T> { public T? db; }执行结果为:
x = 5
str = C#
C#泛型类中的属性
其实在面向对象的程序设计的概念下,为了数据的安全,鼓励程序设计师在类内多多使用属性概念,详情可以参考下列实例。【实例 3】使用属性概念重新设计实例 2。
DataBank<int> x = new DataBank<int>(); x.Db = 5; Console.WriteLine($"x = {x.Db}"); DataBank<string> str = new DataBank<string>(); str.Db = "C#"; Console.WriteLine($"str = {str.Db}"); public class DataBank<T> { public T? Db { get; set; } // Db 属性 }执行结果与实例 2 相同。
C#泛型类内部的多种数据类型
前面介绍了泛型类内含一种泛型数据类型的情况,我们可以将泛型类扩充为含多笔泛型数据类型,例如字典数据就是配对存在的泛型数据类型,读者可以参考下列实例。【实例 4】使用泛型创建字典类型的数据。
DataPair<string, int> noodle = new DataPair<string, int>(); noodle.Key = "牛肉面"; noodle.Value = 180; Console.WriteLine($"{noodle.Key} : {noodle.Value}"); DataPair<string, string> season = new DataPair<string, string>(); season.Key = "春天"; season.Value = "Spring"; Console.WriteLine($"{season.Key} : {season.Value}"); public class DataPair<TKey, TValue> { public TKey? Key { get; set; } public TValue? Value { get; set; } }执行结果为:
牛肉面 : 180
春天 : Spring
有的 C# 程序设计师会在第 1~3 行(或第 3~8 行)声明与创建类对象 noodle(dict)时,采用以下编码方式:
DataPair<string, int> noodle = new DataPair<string, int> { Key = "牛肉面", Value = 180 }; Console.WriteLine($"{noodle.Key} : {noodle.Value}"); DataPair<string, string> season = new DataPair<string, string> { Key = "春天", Value = "Spring" }; Console.WriteLine($"{season.Key} : {season.Value}"); public class DataPair<TKey, TValue> { public TKey? Key { get; set; } public TValue? Value { get; set; } }
C#泛型类内的数组字段
假设泛型内含数组 DataBank,此数组名是 arr,数组大小是 5,则该泛型类的声明方式如下:public class DataBank<T> { public T[] arr = new T[5]; }
【实例 5】声明含数组字段的泛型类,设定数组元素和输出。
DataBank<int> data = new DataBank<int>(); data.arr[0] = 5; data.arr[1] = 10; data.arr[3] = 20; foreach (var item in data.arr) Console.WriteLine(item); public class DataBank<T> { public T[] arr = new T[5]; }执行结果为:
5
10
0
20
0
【实例 6】扩充设计实例 5,增加字符串型数据做测试,同时输出索引值对照。
DataBank<int> data = new DataBank<int>(); data.arr[0] = 5; data.arr[1] = 10; data.arr[3] = 20; Console.WriteLine("以下是整数数组"); for (int i = 0; i < data.arr.Length; i++) Console.WriteLine($"arr[{i}] = {data.arr[i]}"); DataBank<string> str = new DataBank<string>(); str.arr[0] = "C#"; str.arr[1] = "C++"; str.arr[4] = "Java"; Console.WriteLine("以下是字符串数组"); for (int i = 0; i < str.arr.Length; i++) Console.WriteLine($"arr[{i}] = {str.arr[i]}"); public class DataBank<T> { public T[] arr = new T[5]; }运行结果为:
以下是整数数组
arr[0] = 5
arr[1] = 10
arr[2] = 0
arr[3] = 20
arr[4] = 0
以下是字符串数组
arr[0] = C#
arr[1] = C++
arr[2] =
arr[3] =
arr[4] = Java
C#泛型类中的方法
1) 泛型方法的参数是泛型
泛型类内可以设计泛型方法,下列将以实例解说。【实例 7】在泛型类内使用泛型方法 AddItem(),创建泛型数组 arr[ ]。
DataBank<int> x = new DataBank<int>(); x.AddItem(5); x.AddItem(6); x.AddItem(7); x.PrintInfo(); public class DataBank<T> { private T[] arr = new T[5]; // 静态索引变量 static int index = 0; // 泛型方法,建立数组元素 public void AddItem(T item) { arr[index++] = item; } public void PrintInfo() // 输出泛型数组 { for (int i = 0; i < arr.Length; i++) Console.WriteLine($"arr[{i}] = {arr[i]}"); } }执行结果为:
arr[0] = 5
arr[1] = 6
arr[2] = 7
arr[3] = 0
arr[4] = 0
public void AddItem(T item)因为第 6 行声明类时已经定义了泛型 <T>,同时第 8 行也定义了泛型 T 是数组,所以 AddItem 右边不用 <T>,编译程序也可以辨识参数 T item 的数据类型。
2) 泛型方法内有一般参数
泛型方法内可以有泛型参数与一般参数并存,详情可以参考下列实例。【实例 8】更新实例 7,创建泛型数组时,第 1 个参数是索引,第 2 个参数是泛型。
DataBank<int> x = new DataBank<int>(); x.AddItem(0, 5); x.AddItem(2, 6); x.AddItem(4, 7); x.PrintInfo(); public class DataBank<T> { private T[] arr = new T[5]; public void AddItem(int index, T item) // 泛型方法,创建数组元素 { arr[index] = item; } public void PrintInfo() // 输出泛型数组 { for (int i = 0; i < arr.Length; i++) Console.WriteLine($"arr[{i}] = {arr[i]}"); } }执行结果为:
arr[0] = 5
arr[1] = 0
arr[2] = 6
arr[3] = 0
arr[4] = 7
public void AddItem(int index, T item)第 1 个参数 int index 是索引,第 2 个参数 T item 是泛型。
3) 泛型方法的数据类型是泛型
如果我们设计的泛型方法需要回传泛型数据,那么可以将泛型方法的数据类型设为泛型,详情可以参考下列实例。【实例 9】设定泛型方法回传数据为泛型。
DataBank<int> x = new DataBank<int>(); x.AddItem(0, 5); x.AddItem(2, 6); x.AddItem(4, 7); for (int i = 0; i < 5; i++) Console.WriteLine($"arr[{i}] = {x.GetArr(i)}"); public class DataBank<T> { private T[] arr = new T[5]; public void AddItem(int index, T item) // 泛型方法,创建数组元素 { arr[index] = item; } public T GetArr(int index) // 回传泛型数组特定内容 { if (index >= 0 && index < arr.Length) return arr[index]; else return default(T); // 如果超出索引则回传泛型默认值 } }执行结果为:
arr[0] = 5
arr[1] = 0
arr[2] = 6
arr[3] = 0
arr[4] = 7
【实例 10】重新设计实例 9,增加测试输出超出泛型索引的结果,同时设定泛型的类型增加?,这是为了可能有 Null 的参数回传。
DataBank<int> x = new DataBank<int>(); x.AddItem(0, 5); x.AddItem(2, 6); x.AddItem(4, 7); for (int i = 0; i < 5; i++) Console.WriteLine($"arr[{i}] = {x.GetArr(i)}"); Console.WriteLine($"arr[100] = {x.GetArr(100)}"); public class DataBank<T> { private T[] arr = new T[5]; public void AddItem(int index, T item) // 泛型方法,创建数组元素 { arr[index] = item; } public T? GetArr(int index) // 回传泛型数组特定内容 { if (index >= 0 && index < arr.Length) return arr[index]; else return default(T); // 如果超出索引则回传泛型默认值 } }执行结果为:
arr[0] = 5
arr[1] = 0
arr[2] = 6
arr[3] = 0
arr[4] = 7
arr[100] = 0