标签:C# void Cat 参数 泛型 new public
1、泛型类型:泛型类、泛型方法、泛型委托
//泛型类 public class GenericClass<T> { public void GetTypes() { Console.WriteLine(typeof(T).Name); } } public class GenericTypeClass { //泛型方法(指定参数) public void GetVoidType<M>() { Console.WriteLine(typeof(M).Name); } //泛型方法(不指定参数) public void GetEntityType<M>(M t, string name) { Console.WriteLine(t.GetType().Name + name); } //泛型委托(用于泛型参数),只能在泛型类里申明 public delegate void Delegation<T>(T t); //默认三种泛型委托 //带参数,没有返回类型 public Action<string,int> WriteAction = (string s,int a) => Console.WriteLine(s+a); //带参数,有返回类型 public Func<string,bool> FuncTionFunc = (string s)=>string.IsNullOrWhiteSpace(s); //一个参数,只返回bool类型 public Predicate<string> Predication = (string str) => string.IsNullOrWhiteSpace(str); //泛型集合 public Dictionary<string,object> GenericDictionary = new Dictionary<string,object>(); public HashSet<string> GenericHashSet = new HashSet<string>(); }
2、泛型约束
//泛型约束 //值类型参数约束 public void MethodOfStructArgument<T>(T t) where T : struct { } //引用类型参数约束 public void MethodOfObjectArgument<T>(T t) where T : class { } //参数必须有无参构造方法 public void MethodOfNoArgument<T>(T t) where T : new() { } //接口约束 public void MethodOfInterface<T>(T t) where T : 接口名称 { } //父类约束 public void MethodOfFather<T>(T t) where T : 父类名称 { }
3、协变与逆变
//协变逆变只用于泛型接口或泛型委托
现存例子
Cat c = new Cat(); Animal c2 = new Cat(); //用父类接收子类,没问题 List<Cat> catList = new List<Cat>(); //List<Animal> animalList = new List<Cat>(); //编译不通过,因为虽然Animal是Cat的父类,语义正确但是编译器不允许,但是List<Animal>却不是List<Cat>的父类,没有直接的父子关系 IEnumerable<Animal> animalList = new List<Cat>();//编译通过
查看IEnumerable接口,采用了out关键字,协变
public interface IEnumerable<out T> : IEnumerable { new IEnumerator<T> GetEnumerator(); }
委托类型Func也用到了协变
Func<Animal> animalFunc = new Func<Cat>(() => new Cat());
查看Func定义
public delegate TResult Func<out TResult>();
自定义实现
建立父子类
public class Animal { public void breathe() { Console.WriteLine("呼吸"); } } public class Cat:Animal { public void CatchJerry() { Console.WriteLine("抓老鼠"); } }
2.1协变
//协变 IFoo<父类> = IFoo<子类>;左边类型参数是父类,右边类型参数是子类
//要求 T(类型参数)只能是返回值,不能是类型参数
自定义泛型接口fatherInterface及子类sonClass,及说明
public interface fatherInterface<out T> { T getT(); //只能作为返回值,不能作为参数 // void run(T t);//只能作为返回值,不能作为参数 } public class sonClass<T> : fatherInterface<T> { public T getT() { return default(T); } } fatherInterface<Animal> animals = new sonClass<Animal>(); Animal an = animals.getT();//得到的是右边的子类类型,后续若有子类类型调用父类方法肯定是类型安全的
2.2逆变
//逆变:IBar<子类> = IBar<父类>;左边类型参数是子类,右边类型参数是父类
//要求 T(类型参数)只能用于参数,不能是返回值
public interface fatherInterface1<in T> { //T getT(); //只能作为参数,不能作为返回值 void run(T t);//只能作为参数,不能作为返回值 } public class sonClass1<T> : fatherInterface1<T> { public void run(T t) { } } fatherInterface1<Cat> cats = new sonClass1<Animal>(); cats.run(new Cat());//编译器编译时,以左边的参数类型为基准为Cat,所以run方法的参数要传Cat类型,这个方法真实运行时,只要求参数能满足右边类型-Animal即可,Cat一定是Animal所以也没有运行风险
标签:C#,void,Cat,参数,泛型,new,public 来源: https://www.cnblogs.com/summerZoo/p/15850414.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。