泛型学习(二)
3.1 多参数泛型
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApp
{
class MoreGenericSample
{
public static void Main()
{
czrelation<int, double> sinTable = new czrelation<int, double>(180);
for (int i = 0; i < 180; i++)
{
sinTable.Left[i] = i;
sinTable.Right[i] = Math.Sin(Math.PI * i / 180);
}
//求正弦函数
Console.WriteLine("请输入度数(0~179之间):");
int x = int.Parse(Console.ReadLine());
double y = sinTable.Right[x];
Console.WriteLine("sin({0}度={1})", x, y);
//求反正弦函数
Console.WriteLine("请输入一个实数(0~1之间):");
double r = double.Parse(Console.ReadLine());
int pos;
for (pos = 0; pos < sinTable.Length; pos++)
{
if (Math.Abs(r - sinTable.Right[pos]) < 0.005)
break;
}
if (pos == sinTable.Length)
Console.WriteLine("没有找到指定的反正弦值。");
else
Console.WriteLine("arcsin({0})={1}度", r, sinTable.Left[pos]);
Console.ReadLine();
}
}
public class czrelation<L, R> //多参数泛型类
{
public L[] Left;
public R[] Right;
public int Length
{
get { return Left.Length; }
}
public czrelation(int iLength)
{
Left = new L[iLength];
Right = new R[iLength];
}
public int FindLeft(L left)
{
for (int i = 0; i < Length; i++)
{
if (Left[i].Equals(left))
return i;
return -1;
}
return 0;
}
public int FindRight(R right)
{
for (int i = 0; i < Length; i++)
{
if (Right[i].Equals(right))
return i;
return -1;
}
return 0;
}
}
}
3.2 类型参数与标识
关于调用时的歧义 (泛型使用时的类型参数 和 普通方法的参数 相同)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApp
{
class Test<S,T>
{
public static void Add(T t) { Console.WriteLine("T={0}",t); }
public static void Add(int i) { Console.WriteLine("i={0}", i); }
public static void Add(T t, int i) { Console.WriteLine("T={0},i={1}", t,i); }
public static void Add(int i, T t) { Console.WriteLine("i={0},T={1}", i,t); }
public static void Add(S s) { Console.WriteLine("S={0}", s); }
public static void Add(S s, T t) { Console.WriteLine("S={0},T={1}", s, t); }
public static void Add(S s, params T[] ts) { }
public static void Add(T t, params S[] ss) { }
}
class Run
{
static void Main()
{
//存在歧义,如果有一个方法的定义中不带类型参数(T),则调用此方法
Test<int, int>.Add(1);
//存在歧义,如果两个方法的定义中都包含了类型参数,那么代码不能通过编译!
//Test<int,int>.Add(1, 2); //编译错误
//string[] str={"1","2","3"};
//Test<int, string[]>.Add(1,str);
//int[] iArr = { 1, 2, 3 };
//Test<int, int[]>.Add(1, iArr);
Console.ReadLine();
}
}
}
4 类型限制
4.1 主要限制
public class GA<T> where T : struct //限制T的目标类型为 值类型
punlic class GB<B> where T : class //限制T的目标类型为 引用类型
T t = null; //合法
public class CzRelation<L,R> where L : struct where R : class //多参数限制
4.2 次要限制
将类型参数的目标类型 限制为 从指定的基类或接口中的相关成员。
public class A {}
public class GB<T> where T : A //基类限制
public class CzAssemble<T> where T : Ioutput //接口限制
如果存在主要限制,那么次要限制就只能是接口限制, 而且关键字struct或class要在次要限制前面
public class CzAssemble<T> where T : struct, IOutput
Array,Delegate,Enum,ValueType 不能作为类型参数的限制基类
用作类型限制的类可以是泛型类, 此时它的所有类型参数都必须在被限制的类型中出现
public class BaseClass<T>{}
public class GenericClass<T> where T : BaseClass<T> {}
public class CzRelationElement<L,R> {}
public class CzRelation<T> where T : CzRelationElement<int,T>{} //合法
public class CzRelation<T> where T : CzRelationElement<S,T>{} //不合法
4.3 构造函数限制
要求其目标类型必须提供一个默认的无参构造函数
public class CzAssemble<T> where T : IOutput ,new()
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApp
{
class GenericConstraintSample
{
public static void Main()
{
CzAssemble<int> asm = new CzAssemble<int>(5);
Random rand = new Random();
for (int i = 0; i < asm.Length; i++)
asm[i] = rand.Next(100);
asm.Output();
Console.WriteLine("----------------------------------");
asm.Sort();
asm.Output();
Console.ReadLine();
}
}
public interface IOutput
{
void Output();
}
//泛型类:集合CzAssemble
public class CzAssemble<T> where T : IComparable
{
protected T[] m_list;
public int Length
{
get { return m_list.Length; }
}
public T this[int index]
{
get { return m_list[index]; }
set { m_list[index] = value; }
}
public CzAssemble(int length)
{
m_list = new T[length];
}
public void Output()
{
foreach (T t in m_list)
{
if (t != null)
{
if (t is IOutput)
(t as IOutput).Output();
else
Console.WriteLine(t);
}
}
}
public void Sort()
{
T tmp;
for (int i = m_list.Length; i > 0; i--)
{
for (int j = 0; j < i - 1; j++)
{
if (m_list[j].CompareTo(m_list[j + 1]) > 0)
{
tmp = m_list[j];
m_list[j] = m_list[j + 1];
m_list[j + 1] = tmp;
}
}
}
}
}
}
浙公网安备 33010602011771号