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 关键字只适用于委托和接口, 不适用于类, 结构和方法
//

原文地址:https://www.cnblogs.com/blackcatx/p/6541701.html