using System;
delegate T NumberChanger<T>(T n);
namespace ConsoleApp1
{
class TestDelegate
{
static int num = 10;
public static int AddNum(int p)
{
num += p;
return num;
}
public static int MultNum(int q)
{
num *= q;
return num;
}
public static int getNum()
{
return num;
}
}
class Program
{
static void Main(string[] args)
{
//C#泛型(Generic)
//实例
//声明一个整型数组
MyGenericArray<int> intArray = new MyGenericArray<int>(5);
//设置值
for(int c= 0;c < 5; c++)
{
intArray.setItem(c, c * 5);
}
//获取值
for(int c = 0; c < 5; c++)
{
Console.Write(intArray.getItem(c) + " ");
}
Console.WriteLine();
//声明一个字符数组
MyGenericArray<char> charArray = new MyGenericArray<char>(5);
//设置值
for(int i = 0; i< 5;i++)
{
//charArray.setItem(i, (char)(i + 97));
charArray[i] = (char)(i+97);
}
//获取值
for(int i =0;i<5;i++)
{
Console.Write(charArray.getItem(i) + " ");
}
Console.WriteLine();
//泛型的特性
/*
* 使用泛型是一种增强程序功能的技术,具体表现在以下几个方面
* 它有助于最大限度的重用代码、保护类型的安全以及提高性能
* 你可以创建泛型集合类。.Net框架类库在System.Collections.Generic命名空间中包含了一些新的泛型集合类。你可以使用这些泛型集合类来替代System.Collections中的集合类。
* 你可以创建自己的泛型接口、泛型类、泛型方法、泛型事件和泛型委托。
* 你可以对泛型类进行约束以访问特定数据类型的方法
* 关于泛型数据类型中使用的类型的信息可在运行时通过使用反射获取
*/
//泛型方法
int a, b;
char d, e;
a = 10;
b = 20;
d = 'I';
e = 'V';
Console.WriteLine("a = {0}, b = {1}", a, b);
Console.WriteLine("d = {0}, e = {1}", d, e);
Swap<int>(ref a, ref b);
Swap<char>(ref d, ref e);
Console.WriteLine("a = {0}, b = {1}", a, b);
Console.WriteLine("d = {0}, e = {1}", d, e);
//泛型委托
/*
* 你可以通过类型参数定义泛型委托
* delegate T NumberChanger<T>(T n);
*/
//创建委托实例
NumberChanger<int> nc1 = new NumberChanger<int>(TestDelegate.AddNum);
NumberChanger<int> nc2 = new NumberChanger<int>(TestDelegate.MultNum);
//使用委托对象调用方法
nc1(25);//10+25=35
Console.WriteLine("value of Num: {0}", TestDelegate.getNum());
nc2(5);//35*5=175
Console.WriteLine("value of Num: {0}", TestDelegate.getNum());
//泛型限定
/*
* 在声明泛型方法/类的时候。可以给泛型加上一定的约束来满足我们特定的一些条件。
* 比如
* public class CacheHelper<T> where T:new()
* {
* }
* 泛型限定条件:
* T: 结构(类型参数必须是值类型。可以指定除Nullable以外的任何值类型)
* T: 类(类型参数必须是引用类型,包括任何类、接口、委托或数组类型)
* T: new()(类型参数必须具有无参数的公共构造函数。当与其他约束一起使用时new()约束必须最后指定)
* T: <基类名>类型参数必须是指定的基类或派生自指定的基类。
* T: <接口名称>类型参数必须是指定的接口或实现指定的接口。可以指定多个接口约束。接口约束也可以是泛型的。
*/
Console.ReadKey();
}
static void Swap<T>(ref T lhs, ref T rhs)
{
T temp;
temp = lhs;
lhs = rhs;
rhs = temp;
}
}
class MyGenericArray<T>
{
private T[] array;
public MyGenericArray(int size)
{
array = new T[size + 1];
}
public T getItem(int index)
{
return array[index];
}
public void setItem(int index, T value)
{
array[index] = value;
}
public T this[int index]
{
get
{
return array[index];
}
set
{
array[index] = value;
}
}
}
}