泛型的典型应用
本示例程序的功能是找出数组中的最大值和最小值
首先,定义一个泛型结构Pair保存这个值:
public struct Pair<T>
{
public T Max;
public T Min;
}
接着,设计一个泛型类MaxMin,提供一个公有的GetMaxMinVauleFromArray方法封装“查找数组中最大值和最小值算法。
public class MaxMin<T> where T : IComparable<T>
{
//处理数据,获取最大值最小值
public static Pair<T> GetMaxMinVauleFromArray(T[] arr)
{
Pair<T> ret;
ret.Max = arr[0];
ret.Min = arr[0];
for (int i = 1; i <= arr.GetUpperBound(0); i++)
{
if (ret.Max.CompareTo(arr[i]) < 0)
ret.Max = arr[i];
if (ret.Min.CompareTo(arr[i]) > 0)
ret.Min = arr[i];
}
return ret;
}
}
为了进行泛型数组元素的比较,要求类型参数T实现IComparable<T>泛型接口。
C#中的int 和 char 类型都实现了 IComparable<T>泛型接口,因此可以直接拿来用,但复数类ComplecNum是我们自己写的,必须编写代码让它实现IComparblae<ComplexNum>接口。
class ComplexNum:IComparable<ComplexNum>
{
public double a;//实部
public double b ;//虚部
public ComplexNum(double aValue , double bValue )
{
a = aValue;
b = bValue;
}
//按复数标准形式返回a+bi形式的字串
public override String ToString()
{
return (a.ToString() + "+" + b.ToString() + "i");
}
//求复数的模
public double GetMod()
{
return Math.Sqrt(a * a + b * b);
}
//按模比较两个复数的大小
int IComparable<ComplexNum>.CompareTo(ComplexNum other )
{
if (Math.Abs(GetMod() - other.GetMod()) < 0.000001 )
return 0;
if( GetMod() > other.GetMod() )
return 1;
else
return -1;
}
}
现在ComplexNum对象就可以比较大小了以下示例代码在复数数组中查找最大和最小的复数。
public partial class frmGPExample : Form
{
public frmGPExample()
{
InitializeComponent();
}
private char[] CharArray=new char [10];
private int[] IntArray=new int[10] ;
private ComplexNum[] ComplexArray=new ComplexNum[10];
private void OnButtonClick()
{
//填充数组
FillArray();
if (rdoInteger.Checked )
ShowResult<int>(MaxMin<int>.GetMaxMinVauleFromArray(IntArray));
if( rdoChar.Checked )
ShowResult<char>(MaxMin<char>.GetMaxMinVauleFromArray(CharArray));
if (rdoComplex.Checked)
ShowResult<ComplexNum>(MaxMin<ComplexNum>.GetMaxMinVauleFromArray(ComplexArray));
}
private void ShowResult<T>( Pair<T> ret)
{
lblMax.Text = "最大值:" + ret.Max.ToString();
lblMin.Text = "最小值:" + ret.Min.ToString();
}
//用随机数据填充数组,并显示在列表框中
private void FillArray()
{
int i;
Random ran = new Random();
lstData.Items.Clear();
if (rdoInteger.Checked )
for( i = 0 ;i<=IntArray.GetUpperBound(0);i++)
{
IntArray[i] = ran.Next(0, 100);
lstData.Items.Add(IntArray[i]);
}
if (rdoChar.Checked )
for( i = 0 ;i<=CharArray.GetUpperBound(0);i++)
{
int charCode;
charCode = ran.Next(0, 26);
CharArray[i] = (char)('A' + charCode);
lstData.Items.Add(CharArray[i].ToString() + " :ASC码值=" + ((int)CharArray[i]).ToString());
}
int a, b ;
if( rdoComplex.Checked )
for ( i = 0 ;i<=ComplexArray.GetUpperBound(0);i++)
{
a = ran.Next(0, 10);
b = ran.Next(0, 10);
ComplexArray[i] = new ComplexNum(a, b);
lstData.Items.Add(ComplexArray[i].ToString() + " 模=" + ComplexArray[i].GetMod().ToString());
}
}
private void btnFillArray_Click(object sender, EventArgs e)
{
OnButtonClick();//泛型类版本
}
private void btnExit_Click(object sender, EventArgs e)
{
Application.Exit();
}
}