简介
程序开发过程中,为了追求代码的可读性和高利用性,通常我们使用很多措施来尽量提升这方面的性能。可以使用功能类来进行封装高重用性的代码,也可以使用方法重载、方法重写、带有默认值参数的函数方法等措施,除此通用措施之外,C#提供了泛型技术也极大的提升了代码的高利用率。
泛型(Generic)可以实现您在类以及其方法等成员在声明的时候不用考虑具体的适用的数据类型,可以声明一个通用的功能模型,在具体的调用中在对其进行类型约束,也就是允许您延迟编写类或方法中的编程元素的数据类型的规范,直到实际在程序中使用它的时候。个人觉得这种技术最大的优势就是,泛型允许您编写一个可以与任何数据类型一起工作的类或方法。
您可以通过数据类型的替代参数编写类或方法的规范。当编译器遇到类的构造函数或方法的函数调用时,它会生成代码来处理指定的数据类型。下面这个简单的实例将有助于您理解这个概念:
using System;
using System.Collections.Generic;
namespace DreamNoob.GenericApplication
{
public class MyGenericList<T>
{
private List<T> list;
public MyGenericList()
{
list = new List<T>();
}
private int length;
Public int Length
{
get{return list.Count;}
}
public T getItemAt(int index)
{
return list[index];
}
public void AddItem(T value)
{
list.Add(value);
}
public void RemoveItemAt(int index)
{
try{
list.RemoveAt(index);
}
catch
{
Console.WriteLine("数据不存在!");
}
}
}
class Tester
{
static void Main(string[] args)
{
// 声明一个整型列表
MyGenericList<int> intList = new MyGenericList<int>();
//声明一个字符列表
MyGenericList<char> charList = new MyGenericList<char>();
// 填充list列表
for (int c = 0; c < 8; c++)
{
intList.AddItem(c);
charList.AddItem((char)(c+97));
}
// 读取值
Console.WriteLine("intList读取结果:");
for (int c = 0; c < intList.Length; c++)
{
Console.Write(intList.getItemAt(c) + " ");
}
Console.WriteLine("\r\ncharList读取结果:");
for (int c = 0; c < intList.Length; c++)
{
Console.Write(charList.getItemAt(c) + " ");
}
Console.ReadKey();
}
}
}
下面是运行结果:
通过这个简单的例子,我们可以看见泛型在实际应用中巨大的价值了。定义泛型类的时候,不需要要考虑具体的数据类型,使用T来替代,在定义类的内部写完整类要实现的功能逻辑,在具体的调用过程中,再使用具体的数据类型替代T即可。使用泛型,必须对泛型的特性有深刻了解,使用泛型是一种增强程序功能的技术,具体表现在以下几个方面:
- 它有助于您最大限度地重用代码、保护类型的安全以及提高性能。
- 您可以创建泛型集合类。.NET 框架类库在 System.Collections.Generic 命名空间中包含了一些新的泛型集合类。您可以使用这些泛型集合类来替代 System.Collections 中的集合类。
- 您可以创建自己的泛型接口、泛型类、泛型方法、泛型事件和泛型委托。
- 您可以对泛型类进行约束以访问特定数据类型的方法。
- 关于泛型数据类型中使用的类型的信息可在运行时通过使用反射获取。
泛型(Generic)方法
在上面的实例中,我们已经使用了泛型类,我们可以通过类型参数声明泛型方法。下面的程序说明了这个概念:
using System;
using System.Collections.Generic;
namespace DreamNoob.GenericApplication
{
class Program {
static string ToByte<T>(T value)
{
string result = "";
result = Convert.ToByte(value).ToString();
return result;
}
static void Main(string[] args)
{
int a;
char c;
a = 10;
c = 'I';
// 在调用之前显示值
Console.WriteLine("Int values before calling ToByte:");
Console.WriteLine("a = {0}", a);
Console.WriteLine("Char values before calling ToByte:");
Console.WriteLine("c = {0}", c);
// 调用 ToByte()
ToByte<int>(a);
ToByte<char>(c);
// 在调用之后显示值
Console.WriteLine("Int values after calling ToByte:");
Console.WriteLine("a = {0}", a);
Console.WriteLine("Char values after calling ToByte:");
Console.WriteLine("c = {0}", c);
Console.ReadKey();
}
}
}
当上面的代码被编译和执行时,它会产生下列结果:
Int values before calling swap:
a = 10
Char values before calling swap:
c = I
Int values after calling swap:
a = 10
Char values after calling swap:
c = I
泛型(Generic)委托
您可以通过类型参数定义泛型委托。例如:
delegate T CalculateDelegate<T>(T value1,T value2);
下面的实例演示了委托的使用:
using System;
using System.Collections.Generics;
namespace DreamNoob.GenericDelegateApplication
{
delegate T CalculateDelegate<T>(T value1,T value2);
class Test
{
static void Main(string[] args)
{
int a = 42,b = 55;
string s1 = "DreamNoob",s2 = " is a bird just born"
CalculateDelegate<int> intdelegte = new CalculateDelegate<int>(Add);
CalculateDelegate<string> stringdelegate = new CalculateDelegate<string>(CombineString);
int c = intdelegate(a,b);
Console.Write(c.ToString());
string s3 = stringdelegate(s1,s2);
Console.Write(s3);
Console.ReadKey();
}
static int Add(int leftvalue,int rightvalue)
{
return leftvalue+rightvalue;
}
static string CombineString( string value1,string value2)
{
return value1+value2;
}
}
}
当上面的代码被编译和执行时,它会产生下列结果:
97DreamNoob is a bird just born