C#笔记-泛型
/* 》泛型 声明: 在类名之后旋转一组尖括号。 在尖括号中用逗号分隔的占位符字符串来表示希望提供的类型。叫类型参数。 在泛型类声明的主体中使用类型参数来表示应该替代的类型 */ class SomeClass <T1, T2> { public t1 someVar = new T1(); public T2 otherVar = new T2(); } class MyStack<T> { T[] StackArray; int StackPointer = 0; public void Push(T x) { if(!IsStackFull) StackArray[StackPointer++] = x; } public T Pop() { return (!isStackEmpty) ? StackArray[--StackPointer] : StackArray[0]; } const int MaxStack = 10; bool IsStackFull { get{ return StackPointer >= MaxStack;}} bool IsStackEmpty{ get{ return StackPointer <= 0;}} public MyStack() { StackArray = new T[MaxStack]; } public void Print() { for(int i = StackPointer - 1; i >= 0; i-- ) { Console.WriteLine(" Value : {0}", StackArray[i]); } } } class Program { static void Main() { MyStack<int> StackInt = new MyStack<int>(); MyStack<string> StackString = new MyStack<string>(); StackInt.Push(1); StackString.Push("so fun"); StackString.Print(); } } } 扩展方法和泛型类 static class ExtendHolder { pulbic static void Print<T>(this Holder<T> h) { T[] vals = h.GetValues(); Console.WriteLine("......"); } } class Holder<T> { T[] Vals = new T[3]; public Holder(T v0, T v1, T v2) { Vals[0] = v0; vals[1] = v1; } public T[] GetValues() {return Vals;} } class Program { static void main(string[] args) { var intHolder = new Holder<int>(3, 4,5 ); var stringHolder = new Holder<string>("a1", "b2", "c3"); intHolder.Print(); stringHolder.Print(); } } //泛型委托 delegate void MyDelegate<T>(T value); class Simple { static public void PrintString(string s) { Console.WriteLine(s); } static public void PrintUpperString( string s) { ; } } class Program { static void Main() { var myDel = new MyDelegate<String>(simple.PrintString); myDel += Simple.PrintUpperString; myDel("Hi there"); } } /// public delegate TR Func<T1, T2, TR>(T1 p1, T2 p2); class Simple { static public string PrintString(int p1, int p2) { int total = p1 + p2; return total.ToString(); } } class Program { static void Main() { var myDel = new Func<int, int, string>(Simple.PrintString); var str = myDel(1, 2); } } //泛型接品 interface MyTInt<T> { T ReturnIt( T inValue); } class Simple<S> : IMyIfc<S> { public S ReturnIt(S invalue) { return inValue;} } //泛型接口的两个额外的能力: //》与其它泛型相似, 实瑞不同类型的cdovr泛型接口是不同的接口; //》我们可以在非泛型类型中实现泛型接口。 class Simple : IMyIfc<int>, IMyIfc<string> { public int ReturnIt(int inValue) { return inValue;} public int ReturnIt( string inValue ) { return inValue;} } //泛型接口的实现必须唯一 //泛型接口的名字不会和非泛型冲突, 例如, 在前面的代码中我们还可以声明一个名称为ImyIfc的非泛型接口。
2. 协变
//协变convariance 逆变 contravariance 不变 invariance
//如果派生类只是用于输出值, 那么这种结构化的委托有效性之间的常数关系叫做协变。
//为了让编译器知道这是我们的期望, 必须使用out 关键字标记委托声明中的类型参数。
delegate T Factory<out>();
//
//
//逆变
class Animal { public int NumberOfLegs = 4 ; }
calss Dog : Animal {}
class Program
{
delegate void Action1<in T>(T a);
static void ActOnAnimal( Animal a ) { Console.WriteLine( a.NumberOfLegs); }
static void Main()
{
Action1<Animal> act1 = ActOnAnimal;
Action1<Dog> dog1 = act1;
dog1(new Dog());
}
}
//变化只适用于引用类型, 不能从值类型派生其化类型
//in 和out 关键字只适用于委托和接口, 不适用于类, 结构和方法
//