using System;
using System.Collections.Generic;
using System.Text;
namespace Genericity
{
class Program
{
/* 1.什么是泛型
* 2.如何声明和使用泛型
* 3.泛型的好处和原理
* 4.泛型类、泛型方法、泛型接口、泛型委托
* 5.泛型约束
* 6.协变逆变
* 7.泛型缓存
*
* 总结:1.(最重要)泛型用处--让泛型类、泛型方法、泛型接口、泛型委托这些更加通用。
* 2.(次重要)约束--太通用了可能影响安全性,使用泛型约束进行一定约束
* 3.(了解)协变逆变
*/
static void Main(string[] args)
{
//1.什么是泛型
//List<具体类型>
Console.WriteLine("-----------------------泛型List<>-------------------------------");
//List<string> strList = new List<string>() { "ant", "hello", "world" };
//foreach (var item in strList)
//{
// Console.WriteLine(item);
//}
//List<int> intList = new List<int>(){1,2,3,4,5 };
//foreach (var item in intList)
//{
// Console.WriteLine(item);
//}
//List<object> List = new List<object>(){1,2,"hello",5 };//object做数据转换时有装箱拆箱操作,有性能损耗,一般较少使用。
//foreach (var item in List)
//{
// Console.WriteLine(item);
//}
//泛型字典Dictionary<K,Y> Key不能重复
Console.WriteLine("---------------------泛型Dictionary<K,V>-------------------------");
//Dictionary<int, string> dictionary = new Dictionary<int, string>();
//dictionary.Add(1, "jichu");
//dictionary.Add(2, "jinjie");
//dictionary.Add(3, "gaoji");
//foreach (var item in dictionary)
//{
// Console.WriteLine(item.Key.ToString() + " " + item.Value);
//}
//简单查询
//bool isContains = dictionary.ContainsValue("Mongodb");
//Console.WriteLine(isContains);
//删除键对应项
//dictionary.Remove(1);
//foreach (var item in dictionary)
//{
// Console.WriteLine(item.Key + " " + item.Value);
//}
//自定义泛型(泛型最大优点是做到了通用性)
Console.WriteLine("---------------------自定义泛型-------------------------");
//MyGeneric<string> myGeneric = new MyGeneric<string>("自定义泛型");
//myGeneric.Show();
//MyClass myClass = new MyClass("普通类型");//局限于某种特定类型
//myClass.Show();
//2.泛型方法
Console.WriteLine("----------------------泛型方法-------------------------");
//Show("zheshi");
//Show(11111);
//3.泛型约束
Console.WriteLine("----------------------泛型约束-------------------------");
//1.new()约束-表示T类型只接收带一个无参数的构造函数 new()约束一定要写在最后面
//2.strcut值类型约束 值类型:struct/int double bool enum
//3.class引用类型约束 引用类型:数组,类,接口,委托,object,字符串
//4.自定义类型约束(基类约束,接口约束)
//1
//Student student = new Student();
//IStudent student1 = new IStudent();//接口new不了
//Show(student);
//4
//Student2 student2 = new Student2();
//Show(student2);
//2
//Show(int);
//4.协变逆变
Console.WriteLine("----------------------协变和逆变-------------------------");
People people = new People();
People people1 = new Teacher();
Teacher teacher = new Teacher();
//Teacher teacher1 = new People(); //子类对象用父类实例化是不行的
List<People> peoples = new List<People>();
//1.现实中理解如下写法应正确,但List<People>与List<Teacher>不是一个类型,这里其实是语法规则不支持
//List<People> peoples1 = new IList<Teacher>();//不行
//2.协变逆变是针对泛型接口和泛型委托来说的,离开它们就没有这个说法
//3.out关键字代表协变,in关键字代表逆变
//4.什么情况下使用协变逆变:父类通过子类来实例化时需要协变,子类通过父类实例化时需要逆变
IListOut<People> listOut = new ListOut<People>();
IListOut<People> listOut1 = new ListOut<Teacher>();//协变
IListIn<Teacher> listIn = new ListIn<Teacher>();
IListIn<Teacher> listIn1 = new ListIn<People>();//逆变
IOutInList<Teacher, People> myList1 = new OutInList<Teacher, People>();
IOutInList<Teacher, People> myList2 = new OutInList<Teacher, Teacher>();//协变
IOutInList<Teacher, People> myList3 = new OutInList<People, People>();//逆变
IOutInList<Teacher, People> myList4 = new OutInList<People, Teacher>();//协变+逆变
}
//泛型方法
//public static void Show<T>(T t)
//{
// Console.WriteLine(t.ToString());
//}
//泛型约束
//public static void Show<T>(T t) where T : struct//Student//表示只接受Student类型//new()//约束,表示T类型只接收带一个无参数的构造函数new T()
//{
// Console.WriteLine(t);
//}
//public static void Shows<T, S, D, K>(T t)
// where T : class, new()
// where S : struct
// where K : Student, IStudent, IStudent<T>//Student//表示只接受Student类型//new()//约束,表示T类型只接收带一个无参数的构造函数new T()
//{
// Console.WriteLine(t);
//}//泛型多约束 基类约束只能有一个且要放在前面,接口约束可以多个
}
//协变逆变
class People
{
public int Id { get; set; }
}
class Teacher : People
{
public string Name { get; set; }
}
//协变后T只能做返回值,不能做参数
interface IListOut<out T>
{
T GetT();
//void Show(T t);
}
class ListOut<T> : IListOut<T>
{
public T GetT()
{
return default(T);//default关键字,如果是值类型默认返回0,如果是引用类型默认返回null
}
}
//逆变后T只能做参数,不能做返回值
interface IListIn<in T>
{
//T GetT();
void Show(T t);
}
class ListIn<T> : IListIn<T>
{
public void Show(T t)
{
}
}
public interface IOutInList<in inT, out outT>
{
void Show(inT t);
outT Get();
outT Do(inT t);
//out只能是返回值,in只能是参数
//void Show1(outT t);
//inT Get1();
}
public class OutInList<T1, T2> : IOutInList<T1, T2>
{
public void Show(T1 t)//逆变作为参数
{
}
public T2 Get()//协变作为返回值
{
return default(T2);
}
public T2 Do(T1 t)
{
return default(T2);
}
}
//泛型接口
//interface IStudent<T>
//{
//}
//普通接口
//interface IStudent
//{
//没有构造函数
//}
//普通类
//class Student
//{
//默认有一个无参数构造函数
//}
//class Student2
//{
//默认有一个无参数构造函数
//}
//自定义泛型(自定义泛型可以有多个参数)
//class MyGeneric<T>
//{
// private T t;
// public MyGeneric(T t)
// {
// this.t = t;
// }
// public void Show()
// {
// Console.WriteLine(t);
// }
//}
//普通类型
//class MyClass
//{
// private string str;
// public MyClass(string str)
// {
// this.str = str;
// }
// public void Show()
// {
// Console.WriteLine(str);
// }
//}
}
其中对于自定义泛型理解:参数赋值给属性
C#程序在计算机中执行过程: