C# 泛型(Generic)
2021-01-17 21:16
标签:gate blog 函数 组类型 泛型方法 generic names object target 允许延迟编写类或方法中的编程元素的数据类型的规范,直到实际在程序中使用它的时候 在泛型类型的定义中,出现的每个T(一个展位变量而已叫别的名字也行)在运行时都会被替换成实际的类型参数。 现在有一个需求,需要写一个方法,这个方法传入的参数可能是int型的,也可能是string型的。首先我们可以用方法的重载方案解决这个问题,比如下面两个重载方法: 但是这样的话如果支持的类型变多了,那么你需要写很多重载方法。如果只写一个重载方法,则可以写成 但是这样写又出现object转成其他类型的问题,会带来效率损失。同时不检查类型,一旦传入了不支持的类型,可能会出问题。 现在把test方法改造一下,这样写: 这样写之后,使用的时候要求提前通知这个方法,你传入的是什么类型,即: 如果写成 test 这就是泛型方法。这里面我们省略了方法内部的实现,其实仔细想一下,如果要在这样的方法里面添加业务代码,似乎除了用于存放数据的集合之外,并没有多少场景需要这么写方法。没错,泛型这个东西最常用的应用场景就是数据集合。而List 上面的方法:public void test 你会发现,如果把 这不就是我们经常用的List 参考链接:https://www.cnblogs.com/ypa-yap-yap/p/11523736.html 为什么要泛型约束,其主要问题还是解决安全问题,规范开发人员写代码的规范性,避免一些在运行时期才能检查到的错误。比如下面的代码,在编译器是不会报错的,但是在运行期会出现转换异常。 所谓的泛型约束,实际上就是约束的类型T。使T必须遵循一定的规则。比如T必须继承自某个类,或者T必须实现某个接口等等。那么怎么给泛型指定约束?其实也很简单,只需要where关键字,加上约束的条件。 在OO的世界里,可以安全地把子类的引用赋给父类引用。但是在T的世界里,就不一定了。有的能变,有的不能变,先了解以下几点: 如果不能理解以上几句话,就先看下面的知识点 所谓协变,就是为了解决子类泛型接口或委托能回到父类泛型接口或委托上来。(Foo = Foo ) 所谓协变,就是为了解决父类泛型接口或委托能回到子类泛型接口或委托上来。(Foo = Foo) 注意 in/out是什么意思呢?为什么加了它们就有了“变”的能力,是不是我们定义泛型委托或者接口都应该添加它们呢? 泛型在声明的时候可以不指定具体的类型,但是在使用的时候必须指定具体类型; 如果子类也是泛型的,那么继承的时候可以不指定具体类型 类实现泛型接口也是这种情况 参考链接:https://www.cnblogs.com/zhan520g/p/10397117.html#idx_10 C# 泛型(Generic) 标签:gate blog 函数 组类型 泛型方法 generic names object target 原文地址:https://www.cnblogs.com/zhaoyl9/p/12174500.html泛型(Generic)
泛型方法
public void test(int param)
{ }
public void test(string param)
{ }
public void test(object param) { }
public void test
testint>(10);
泛型类
class TClass
class List
泛型约束
public class 动物
{
}
public class 狗 :动物
{
}
public class 猫
{
}
public class Generic
{
public void method(object cat)
{
动物 animal= (动物)cat;
}
}
序号
约束
说明
1
T:struct
类型参数必须是值类型
2
T:class
类型参数必须是引用类型;这一点也适用于任何类、接口、委托或数组类型。
3
T:new()
类型参数必须具有无参数的公共构造函数。 当与其他约束一起使用时,new() 约束必须最后指定。
4
T:基类名
类型参数必须是指定的基类或派生自指定的基类。
5
T:接口名称
类型参数必须是指定的接口或实现指定的接口。 可以指定多个接口约束。 约束接口也可以是泛型的。
6
T:基类名,接口名称,new()
泛型约束也可以同时约束多个,但是new()必须放在最后
泛型的协变和逆变
协变
//泛型委托:
public delegate T MyFuncA
逆变
public delegate void MyActionA
原来,在泛型参数上添加了in关键字作为泛型修饰符的话,那么那个泛型参数就只能用作方法的输入参数,或者只写属性的参数,不能作为方法返回值等,总之就是只能是“入”,不能出。out关键字反之。使用注意点(重点)
注意点1
namespace MyGeneric
{
///
注意点2
namespace MyGeneric
{
///
下一篇:C#窗体简单增删改查