首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

C#规范整理·泛型委托事件

4.使用default为泛型类型变量指定初始值# 有些算法,比如泛型集合List<T>的Find算法,所查找的对象有可能会是值类型,也有可能是引用类型。...于是,问题来了:值类型变量的默认初始值是0值,而引用类型变量的默认初始值是null值,显然,这会导致下面的代码编译出错: public T Func() { T t=null;...11.使用泛型参数兼容泛型接口的不可变性# 让返回值类型返回比声明的类型派生程度更大的类型,就是“协变”。...所以,泛型类型参数这种模式是满足“协变”的定义的。但是,只要将T作为输入参数,便不满足“协变”的定义了。...在我们自己的代码中,如果要编写泛型接口,除非确定该接口中的泛型参数不涉及变体,否则都建议加上out关键字。协变增大了接口的使用范围,而且几乎不会带来什么副作用。

27830

C# 发展历史及版本新功能介绍

到达迭代器方法的结尾时,循环便已完成。 协变和逆变 在 C# 中,协变和逆变能够实现数组类型、委托类型和泛型类型参数的隐式引用转换。 协变保留分配兼容性,逆变则与之相反。...可通过使用 new 运算符和对象初始值创建匿名类型。 有关对象初始值设定项的详细信息,请参阅对象和集合初始值设定项。...泛型协变和逆变 协变和逆变都是术语,前者指能够使用比原始指定的派生类型的派生程度更大(更具体的)的类型,后者指能够使用比原始指定的派生类型的派生程度更小(不太具体的)的类型。...泛型类型参数支持协变和逆变,可在分配和使用泛型类型方面提供更大的灵活性。 在引用类型系统时,协变、逆变和不变性具有如下定义。...以下介绍了部分功能: 静态导入 异常筛选器 属性初始值设定项 Expression bodied 成员 Null 传播器 字符串内插 nameof 运算符 字典初始值设定项 这些功能每一个都很有趣。

4.2K20
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    C#7.3 新增功能

    以下新增功能支持使安全代码获得更好的性能的主题: 无需固定即可访问固定的字段。 可以重新分配 ref 本地变量。 可以使用 stackalloc 数组上的初始值设定项。...1.3 stackalloc 数组支持初始值设定项 当你对数组中的元素的值进行初始值设定时,你已能够指定该值: var arr = new int[3] {1, 2, 3}; var arr2 = new...有关详细信息,请参阅有关 where 泛型约束和类型参数的约束的文章。 将这些约束添加到现有类型是不兼容的更改。 封闭式泛型类型可能不再满足这些新约束的要求。...2.4 扩展初始值设定项中的表达式变量 已对在 C# 7.0 中添加的允许 out 变量声明的语法进行了扩展,以包含字段初始值设定项、属性初始值设定项、构造函数初始值设定项和查询子句。...静态上下文(其中隐式 this 实例接收器无法使用)包含未定义 this 的成员的正文(例如,静态成员),以及不能使用 this 的位置(例如,字段初始值设定项和构造函数初始值设定项)。

    1.7K10

    Swift 中的属性包装器

    除此之外,唯一真正的要求是每个属性包装类型应该包含一个名为wrappedValue的存储属性,该属性告诉 Swift 要包装的是哪个底层值。...init(wrappedValue:)初始值设定项(就像我们的Capitalized那样),那么我们甚至可以在本地为包装的属性分配默认值,如下所示: struct Document { @Capitalized...属性的属性 属性包装器也可以有自己的属性,并且支持进一步的定制,甚至可以将依赖项注入到包装器类型中。...我们所要做的就是将defaultValue属性添加到包装器中,然后在底层UserDefaults存储不包含属性键的值时使用它。...——我们可以给它们属性、初始值设定项甚至扩展——这反过来又使我们能够使我们的调用站点真正整洁干净,并充分利用Swift强大的类型系统。

    2.7K30

    C#基础篇——泛型

    无论存储数据的类型如何,添加项和从集合删除项等操作的执行方式基本相同。.../// 2 通过继承,子类拥有父类的一切属性和行为;任何父类出现的地方,都可以用子类来代替 /// object引用类型 加入传个值类型int 会有装箱拆箱 性能损失 /...可以看到,在泛型接口的T前面有一个out关键字修饰,而且T只能是返回值类型,不能作为参数类型,这就是协变。使用了协变以后,左边声明的是基类,右边可以声明基类或者基类的子类。...MyList();//逆变+协变 有关可变性的注意事项 变化只适用于引用类型,因为不能直接从值类型派生其他类型 显示变化使用in和out关键字只适用于委托和接口,不适用于类、...8、KeyedCollection 是介于列表和字典之间的混合类型,它提供了一种存储包含自己键的对象的方法。

    1.3K40

    《Rust for Rustaceans》 样章试译 | 第二章 Rust 基础

    常量项(Const Item)可以在编译时被完全计算出来,任何引用它们的代码在编译时都会被常量的计算值所取代。一个常量没有与之相关的内存或其他存储空间(它不是一个位置)。...共有三种型变:协变(covariant)、不变(invariant)和逆变(contravariant)。如果你只可以使用子类型来代替一个类型,那么该类型就是协变的。...例如,如果一个变量是 &'a T类型,那么你可以给它提供一个&'static T类型的值,因为&'a T在'a上是协变的。...&'a T在 T上也是协变的,所以你可以把&Vec传给一个接受&Vec的函数。 有些类型是不变的,这意味着你必须准确提供给定的类型。...不变要求相关类型永远不会被子类型或父类型取代,所以编译器缩短借用的尝试失败了,它报告该清单仍然有可变借用! 总之,你要确保类型在尽可能多的泛型参数上保持协变(或者在适当的时候保持逆变)。

    5.9K31

    PHP类与对象

    要创建一个新实例必须使用克隆操作类的属性和方法存在与不同的空间,所以同一个类的属性和方法可以使用同样的名称使用extends实现类继承,PHP只支持单继承。::class类名解析nullsafe操作符,对象引用解析为null时不抛出异常,而是返回null属性属性、方法、抽象方法、静态方法、静态属性匿名类重载PHP中的重载是指在访问未定义的属性、方法时,会调用特定的魔术方法属性重载:__set()__get...()__isset()__unset()方法重载:__call()__callStatic()遍历对象对象的可见属性都将被遍历魔术方法后期静态绑定self::代表的是当前方法所在的类的实例static:...B extends A { public static function who() { echo __CLASS__; }}B::test(); // Output: B协变与逆变协变使子类比父类方法能返回更具体的类型逆变使子类比父类方法参数类型能接受更模糊的类型

    1.6K10

    流畅的 Python 第二版(GPT 重译)(八)

    有时需要将注释存储为字符串,因为存在“前向引用”问题:当类型提示需要引用在同一模块下定义的类时。然而,在源代码中问题的常见表现根本不像前向引用:当方法返回同一类的新对象时。...上协变类型参数的常规后缀。...变异回顾 变异是一个微妙的属性。以下部分总结了不变、协变和逆变类型的概念,并提供了一些关于它们推理的经验法则。...协变泛型类型遵循实际类型参数的子类型关系。 不可变容器可以是协变的。...协变的经验法则 最后,以下是一些关于推理方差时的经验法则: 如果一个形式类型参数定义了从对象中输出的数据类型,那么它可以是协变的。

    24210

    认真CS☀️协变、逆变 & 不变

    >类了,无法赋值给同级别的Factory类),而是直接将它的引用MakeDog赋值给animal,这是可行的 2、我们还有一种方法,那就是协变(在类型参数前加out)(派生类只是用来输出值...) “协变”是指能够使用与原始指定的派生类型相比,派生程度更大的类型。...in关键字指明类型参数是逆变的 逆变:在类型参数前加in 基类对象的引用期望的是传入到基类对象,但实际上(也允许它)传入到派生对象,这叫做逆变 这样可以工作,因为在调用的时候,调用代码传入了派生类型的变量...协变(out)是将派生类对象的引用传入到基类对象,输出派生类的值 逆变(in)是将基类对象的引用传入到派生对象,派生对象只能操作基类部分 接口的协变和逆变 1️⃣ 接口的协变 using System...因此变化只是用于引用类型,不能从值类型派生其他类型 b、显式变化使用in和out关键字只适用于委托和接口,不适用于类、结构和方法 c、不包括in、out关键字的委托和接口类型参数叫不变。

    10210

    【游戏开发】在Lua中实现面向对象特性——模拟类、继承、多态

    但是作为一款脚本语言,Lua也有着自己的不足,那就是它本身并没有提供面向对象的特性,而游戏开发是一项庞大复杂的工程,如果没有面向对象功能势必会为开发带来一定的不便。...(3)table 的默认初始索引一般以 1 开始,如果不写索引,则索引就会被认为是数字,并按顺序自动从1往后编;   (4)table 的变量只是一个地址引用,对 table 的操作不会产生数据影响;...下面我们就用Lua中的table和元表实现一下模拟类中的这些特性,Class.lua 代码如下: 1 --类的声明,这里声明了类名还有属性,并且给出了属性的初始值 2 Class = {x=0,y=...+ 1 21 self.y = self.y + 1 22 end   简单解释一下,在Lua中的类,其实都是table,因为table既可以存储普通变量又可以存储函数或者另一个table,利用这个特性...(self, SubClass) --将对象自身元表设定为SubClass类 14 self.z= z --新的属性初始化,如果没有将会按照声明=0

    3K20

    C# 9.0 中的新增功能

    localsinit 标志 目标类型的新表达式 静态匿名函数 目标类型的条件表达式 协变返回类型 扩展 GetEnumerator 支持 foreach 循环 Lambda 弃元参数 本地函数的属性...模块初始值设定项 分部方法的新功能 .NET 5 支持 C# 9.0。...遗憾的是,C# 强制编写大量额外的代码来创建不可变的引用类型。 记录为不可变的引用类型提供类型声明,该引用类型使用值语义实现相等性。...属性初始值设定项可明确哪个值正在设置哪个属性。 缺点是这些属性必须是可设置的。 从 C# 9.0 开始,可为属性和索引器创建 init 访问器,而不是 set 访问器。...协变返回类型为替代函数的返回类型提供了灵活性。 替代的虚函数可返回从基类方法中声明的返回类型派生的类型。 这对于记录和其他支持虚拟克隆或工厂方法的类型很有用。

    1.7K20

    Java泛型的协变与逆变

    []类型的变量实际引用的数组完全可以是Integer[]、也可是Float[]、也可是Double[].........注意 对于一个强大的编译器来说,如果程序在编译阶段没有警告、没有错误 ,那么运行时就不应该导致简单的语法错误——上面程序编译阶段没有错误,但运行时仅仅只是因为类型不兼容(Java是强类型语言)而出错,这显然是不尽人意的...因此对于协变的泛型集合,程序只能从集合中取出元素——取出的元素的类型肯定能保证是上限;但程序不能向集合添加元素——因此程序无法确定程序要求的集合元素具体是上限的哪个子类。...对于更通用的泛型来说,对于支持协变的泛型,程序只能调用以泛型为返回值类型的方法;不能调用形参为泛型的方法。例如如下代码。...因此对于逆变的泛型集合,程序只能向集合中添加元素——添加元素的类型总能符合上限——而集合元素总是上限的父类,因此完全没问题;但程序不能从集合中取出元素——因为编译器无法确定集合元素具体是下限的哪个父类—

    1.3K40

    了解C#的协变和逆变

    前言 在引用类型系统时,协变、逆变和不变性具有如下定义。 这些示例假定一个名为 Base 的基类和一个名为 Derived的派生类。...Invariance 表示只能使用最初指定的类型。 固定泛型类型参数既不是协变,也不是逆变。 你无法将 List 的实例分配给 List 类型的变量,反之亦然。...,有下面的约束,否则则会在编译时报错: 泛型参数占位符以out关键子标识,并且占位符T只能用于只读属性、方法或者委托的返回值,out简而易懂,就是输出的意思 当要进行类型转换,占位符T要转换的目标类型也必须是其基类...、方法或者委托的输入参数 当要进行类型转换,占位符T要转换的目标类型也必须是其子类,上述例子则是FooBase转为Foo 总结 协变和逆变只对泛型委托和泛型接口有效,对普通的泛型类和泛型方法无效 协变和逆变的类型必须是引用类型...,因为值类型不具备继承性,因此类型转换存在不兼容性 泛型接口和泛型委托可同时存在协变和逆变的类型参数,即占位符T 参考 泛型中的协变和逆变 | Microsoft Docs 《你必须知道的.NET(第2

    94810

    C++ 动态新闻推送 第33期

    讲各种各样的cast 这里着重介绍一下bit_cast,这个就是强制解释的memcpy版本,对于内建基础类型使用的,比如 #include #include #include...让编译器不优化,AssemblerTemplate是空的,也就是明显是空的无作用的汇编也不要删掉?...,所以,要标记value是可变只能从内存读/寄存器读读(clobber memory)这样就有全局副作用,对于相关的函数调用,能保证不被重排。...没啥看头 Generators, Coroutines and Other Brain Unrolling Sweetness 一个协程的介绍 介绍了协程的几个猥琐用法 比如用于树的遍历,协程的栈比函数栈要省...没啥说的 Runtime Reflection in C++ 介绍一种reflect实现,还是传统的宏+记录类型信息 项目 weggli rust写的一个程序,能够搜索代码中的代码块。

    54120

    精:C#历来版本特性一览

    版本一览 C# 1.0 发布日期:2002 年 1 月 一切的开始,由于我是从 2.0 开始接触 C# 的,在此不赘述该版本了,只能说 C# 的起点不低,从 Java 转过来上手很快,兼具 C 语族的语法特点...】 迭代器【yield return 语句】 协变和逆变【这时候还不支持泛型接口和委托】 getter/setter 单独可访问性 静态类 C# 3.0 发布日期:2007 年 11 月 C# 3.0...自动实现的属性【{ get; set; } 写法】 匿名类型【new { Foo = 108, Bar = "Hello" } 写法】 查询表达式【from foo select bar where baz...写法】 Lambda 表达式 表达式树 扩展方法 隐式类型本地变量【var 关键字】 分部方法【partial 关键字可以作用在方法上,没用过该特性】 对象和集合初始值设定项【Foo foo = new...命名实参和可选实参【可以少些一些方法重载了】 泛型协变和逆变【完全体,但一般只有底层类库设计者需要考虑这玩意】 嵌入的互操作类型【没什么存在感】 System.Threading.Tasks 命名空间【

    22620

    2022年Unity面试题分享

    值类型:数据存储在栈上,超出作用域就自动清理 引用类型:数据存储在托管堆上,引用地址在线程栈上,地址指向数据存放的堆上 托管堆会由GC来自动释放 ,线程栈数据在作用域结束后会被清理。...,特性,动态扩容,泛型安全 将泛型数据(对值类型来说就是数据本身,对引用类型来说就是引用)存储在一个泛型数组中,添加元素时若超过当前泛型数组容量,则以2倍扩容,进而实现List大小动态可变。...Directionary字典,有序,泛型存储不需要进行类型装换(不需要装箱拆箱),碰撞阈值扩容~ HashSet:一组不包含重复的元素集合【LeetCode算法217存在重复元素...参数可以不赋值,带回返回值之前必须明确赋值, 引用参数和输出参数不会创建新的存储位置 如果ref参数是值类型,原先的值类型数据,会随着方法里的数据改变而改变, 如果ref参数值引用类型,方法里重新赋值后...本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

    4.1K11

    深入类型系统_TypeScript笔记8

    :要求满足双变性约束 函数类型的双变性(bivariance) 双变是指同时满足协变和逆变,简单地讲: 协变(covariant):允许出现父类型的地方,也允许出现子类型,即里氏替换原则 逆变(contravariant...):协变反过来,即允许出现子类型的地方,也允许出现父类型 双变(bivariant):同时满足协变和逆变 不变(invariant或nonvariant):既不满足协变也不满足逆变 协变很容易理解,子类型兼容父类型...,此外还具有一些(父类型不具备的)扩展属性或方法,因此用子类型换掉父类型后,仍能正常工作(类型安全) 而逆变并不很直观,什么场景下,用父类型换掉子类型后,仍能保证类型安全呢?...,子类型允许类型之间有层级(继承)关系,从宽泛类型到特殊类型,而协变、逆变等关系就建立在这种类型层级之上: 协变:简单类型的层级关系保留到了复杂类型,这个复杂类型就是协变的,例如Animal是Cat的父类型...,而数组Animal[]也是Cat[]的父类型,所以数组类型是协变的 逆变:简单类型的层级关系到复杂类型中反过来了,这个复杂类型就是逆变的。

    99340

    Swift 面向对象解析(一)

    存储属性可以分为  实例存储属性  类型存储属性 两类。这个可以参考OC的实例方法和类型方法,实例变量和类型变量一样的道理去理解。          ...2 : Swift 要求所有的存储属性都必须显式的制定初始值,要么你在定义的时候指定初始值,要么你在构造器里面指定初始值。          ...3 : 如果将存储属性的类型申明为可选类型,系统就可以将这些属性的初始值设置为 nil (大家一定注意,Swift的nil和OC的nil完全不一样,Swift的nil是一个确定的值,叫缺失值,而OC的nil...是一个不指向任何类型的指针)。        ...,我们要注意的是这个,延迟存储属性,延迟存储属性是指在第一次调用时才会被计算初始值的属性,声明延迟存储属性需要使用 Lazy 修饰符。

    1.8K70

    《Kotlin 程序设计》第三章 Kotlin 类型系统第三章 Kotlin 类型系统基本数据类型2.字符类型CharKotlin类型系统参考资料

    我们知道,Java的数组是协变的。与 Java 不同的是,Kotlin 中数组是非协变的(invariant)。...T的类型是Int val box2 = Box(1) println(box2.value) 在Kotlin泛型中,数组类型Array是非协变的(Non covariant)。...在Java中的使用通配符类型的场景中,Kotlin通过使用关键字out,in来支持特殊场景下的协变(covariant)。 Java类型系统最复杂的特性之一,就是通配符。...首先,Java中泛型的参数化类型是非协变的(invariant),这意味着List并不是List的子类型。...extends Object>的子类。从表面意义来看,通过extends-bound(向上限制)修饰的通配符使得类型可协变。 Java中的另一个通配符 List<?

    1.4K30
    领券