泛型的约束理解 不念不忘少年蓝@ 2021-06-26 16:06 384阅读 0赞 ## 1.引用类型约束 ## `struct RefSample<T> where T:class` 引用类型用`Class`表示约束,其他的引用类型为具体的约束。 表示对于的约束必须为一个类(引用类型)不能是值类型(`int,char,datatime,struct`),可以是接口`interface` 区分,数组为引用类型,因为定义数组时需要`new`出一个对象。 虽然定义成 `RefSample<T>` 传入的必须为引用类型 但是`RefSample`仍然为值类型 ## 2.值类型约束 ## class ValSample<T> where T:struct 为引用类型,因为`int`,`char`等类型都是`struct` ![这里写图片描述][20180912134217812] ValSample<int> ## 3.构造函数类型约束 ## public T CreateInstance<T>() where T:new() { return new T(); } 指定的类型`T`必须有构造函数,`CreateInstance<int>`和`CreateInstance<object>` 都是有效的。但是`CreateInstance<strings>`没有构造函数。 ## 4.转换类型约束 ## 一种约束允许你指定另一个类型,类型实参必须可以通过一致性、引用或装箱转换隐式地转换为该类型。你还可以规定一个类型实参必须可以转换为另一个类型实参——这称为类型参数约束。 理解的意思:可以互换,就是我们可以通过装箱或者强制类型转换成目标类型的 类型都可以用于类型参数传入。 class Sample<T> where T:Stream 有效:`Sample<Stream>` 这本身符合约束 无效:`Sample<String>` 因为`String`类型无法通过引用或者装箱拆箱强制转换成Stream、 struct Sample<T> where T:IDisposable 规定T必须为`IDisposable` 类型的 引用类型 有效:`Sample<SqlConnection>`引用转换 无效:`Sample<StringBuilder>` 分析:为什么`SqlConnection` 可以而`StringBuilder`不可以?它们都是引用类型 1.`SqlConnection`实现了`IDisposable`接口,所以可以协变 ![这里写图片描述][20180912131025968] ![这里写图片描述][20180912134313199] 2.`StringBuilder`只实现了`ISerializable`接口,无法通过途径转换为`IDisposable` ![这里写图片描述][20180912134330379] class Sample<T> where T:IComparable<T> 因为将`IComparable<T>`整体当作约束,分析`IComparable<T>`的类型,可以用`Type.IsValueType`判断,`true`为值类型,`false`为引用类型 `typeof(IComparable<T>).IsValueType` 结果为`false`表示为引用类型 有效:`Sample<int>`(装箱转换) 无效:`Sample<FileInfo>` 也可以指定多种约束: class sample<T> where T:stream,IEnumerable<string>,IComparable<int> class Sample<T,U> where T:U 有效:`Sample<Stream,IDisposable>` 无效:`Sample<string,IDiposable>` 总结:要看传入类参数是否可以转换,查看规定参数和传入类参数是否实现同一接口,如果实现则可以,否则不可以。 不可以是以下:`System.Object,System.Enum,System.ValueType,System.Delegate`,结构或密封类(`String`) ## 5.组合约束 ## 对类型参数的约束有多个,注意:只能是一种类型,值类型和引用类型不能同时存在,没用一个类型即是引用类型,又是值类型。 由于每一个值类型都有一个无构造函数,此后不能再有构造函数约束 有效: class Sample<T> where T:class,IDisposable,new() class Sample<T,U> where T:Stream where U:IDispsable 无效: `class Sample<T> where T:class,struct` (没有任何类型即时引用类型又是值类型的,所以为无效的) `class Sample<T> where T:Stream,class` (引用类型约束应该为第一个约束,放在最前面,所以为无效的) `Stream`只是约束传入参数为`Stream`具体类型,而`class`约束为引用类型,一开始我理解错了 `class Sample<T> where T:new(),Stream` (`new()` 必须放在最后) `class Sample<T> where T:IDisposable,Stream` (类必须放在接口前面,所以为无效的) `class Sample<T> where T:XmlReader,IComparable,IComparable` (对于转换类型约束,同一个接口不能出现多次) `class Sample<T,U> where T:struct where U:Class,T` (类型形参“T”具有“struct”约束,因此“T”不能用作“U”的约束,所以为无效的) `class Sample<T,U> where T:Stream ,U:IDisposable` 语法错误 看到网上还有这种版本也是有效的我表示不理解: `class Sample<T> where T:struct,IDisapsable IDisapsable`为值类型? `class Sample<T,U> where T:class where U:struct ,T` `T`为引用类型为何与值类型一起约束`U`? 希望可以指正 [20180912134217812]: /images/20210626/81f3ed3d385b48b18158c606315af810.png [20180912131025968]: /images/20210626/afe55774e7df44648c5d54f3ed9302d6.png [20180912134313199]: /images/20210626/e422119ebdb94ef0b64e09d85caa25f1.png [20180912134330379]: /images/20210626/52a98fdaef384365a6a37f9fc64f9eaf.png
相关 Java泛型与约束理解:通配符*和?的区别 在Java的泛型中,`*`和`?`是两个特殊的通配符,用于表示任意类型的实例。 1. `*`(星号): 通常用于数组或列表的类型参数。例如: ```java 桃扇骨/ 2024年09月19日 18:36/ 0 赞/ 2 阅读
相关 理解Java中的泛型及其边界约束 在Java中,泛型是一种类型参数化的方式,它允许我们创建可以处理多种数据类型的类。 1. 泛型声明: ```java // 基本的泛型声明,后面可以跟类型参数 偏执的太偏执、/ 2024年09月11日 16:18/ 0 赞/ 21 阅读
相关 理解Java泛型约束及其违反带来的问题 Java泛型是一种在编译时确定数据类型的技术。它允许我们创建可以存储任何类型的对象的列表、集合等。 泛型约束主要有以下几种: 1. 类型参数:如`List<String>` 深藏阁楼爱情的钟/ 2024年09月10日 15:42/ 0 赞/ 17 阅读
相关 C#泛型 where约束 [where(泛型类型约束)][where] 定义:在定义泛型的时候,我们可以使用 where 限制参数的范围。 使用:在使用泛型的时候,你必须尊守 where 限制参数的 电玩女神/ 2022年06月18日 01:12/ 0 赞/ 197 阅读
相关 泛型约束 要T是继承于A where T: A 要T继承于B的 where T: B 在定义泛型类时,可以对客户端代码能够在实例化类时用 桃扇骨/ 2022年05月20日 01:39/ 0 赞/ 205 阅读
相关 Java 泛型 泛型的约束与局限性 不能用基本类型实例化类型参数 不能用类型参数代替基本类型:例如,没有Pair,只有Pair,其原因是类型擦除。擦除之后,Pair类含有Object类型的域,而Obje 朱雀/ 2021年07月24日 22:45/ 0 赞/ 399 阅读
相关 泛型的约束理解 1.引用类型约束 `struct RefSample<T> where T:class` 引用类型用`Class`表示约束,其他的引用类型为具体的约束。 表示对于的约 不念不忘少年蓝@/ 2021年06月26日 16:06/ 0 赞/ 385 阅读
相关 C#泛型约束 六种类型的约束: <table> <thead> <tr> <th align="left">格式</th> <th align="left">描述 た 入场券/ 2021年06月26日 16:06/ 0 赞/ 415 阅读
还没有评论,来说两句吧...