C# 泛型
2022/1/27 17:34:31
本文主要是介绍C# 泛型,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
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# 泛型的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2022-03-01沐雪多租宝商城源码从.NetCore3.1升级到.Net6的步骤
- 2024-12-06使用Microsoft.Extensions.AI在.NET中生成嵌入向量
- 2024-11-18微软研究:RAG系统的四个层次提升理解与回答能力
- 2024-11-15C#中怎么从PEM格式的证书中提取公钥?-icode9专业技术文章分享
- 2024-11-14云架构设计——如何用diagrams.net绘制专业的AWS架构图?
- 2024-05-08首个适配Visual Studio平台的国产智能编程助手CodeGeeX正式上线!C#程序员必备效率神器!
- 2024-03-30C#设计模式之十六迭代器模式(Iterator Pattern)【行为型】
- 2024-03-29c# datetime tryparse
- 2024-02-21list find index c#
- 2024-01-24convert toint32 c#