四川外国语大学网站建设系wordpress 3.5 官方中文版

diannao/2025/10/21 18:56:50/文章来源:
四川外国语大学网站建设系,wordpress 3.5 官方中文版,WordPress外链自动转内链,品牌vi设计案例欣赏ppt前言C# 对类型系统进行改进一直都没有停过#xff0c;这是一个长期的过程。C# 8 之后则主要围绕扩展性方面进行各种改进#xff0c;目前即将发布的 C# 11 中自然也包含该方面的进度。这些改进当然还没有做完#xff0c;本文则介绍一下已经推出和即将推出的关于这方面改进的新… 前言C# 对类型系统进行改进一直都没有停过这是一个长期的过程。C# 8 之后则主要围绕扩展性方面进行各种改进目前即将发布的 C# 11 中自然也包含该方面的进度。这些改进当然还没有做完本文则介绍一下已经推出和即将推出的关于这方面改进的新特性。接口我们从最初的最初开始说起。接口interface在 C# 的类型系统中是一个非常关键的部分用来对行为进行抽象例如可以抽象“能被从字符串解析为整数”这件事情的接口可以定义为interface IIntParsable {int Parse(string text); }这样一切实现了该接口的类型就可以直接转换为 IIntParsable然后调用其 Parse 方法把 string 解析成 int用来根据字符串来创建整数class IntFactory : IIntParsable {public int Parse(string text) { ... } }但是这样显然通用性不够如果我们不想创建 int而是想创建其他类型的实例的话就需要定义无数个类型不同而抽象的事情相同的接口或者将 Parse 的返回值改成 object这样就能通用了但是对值类型会造成装箱和拆箱导致性能问题并且调用方也无法在编译时知道 Parse 出来的到底是个什么类型的东西。泛型接口为了解决上面的这一问题C# 进一步引入了泛型。泛型的引入允许接口定义类型参数因此对于上面的接口而言不再需要为不同类型重复定义接口而只需要定义一个泛型接口即可interface IParsableT {T Parse(string text); }这样当一个类型需要实现 IParsableT 时就可以这么实现了class IntFactory : IParsableint {public int Parse(string text) { ... } }由此我们诞生了各式各样的工厂例如上面这个 IntFactory 用来根据 string 来创建 int。基于这些东西甚至发展出了一个专门的工厂模式。但是这么做还有一个问题假如我在接口中添加了一个新的方法 Foo那么所有实现了这个接口的类型就不得不实现这个新的 Foo否则会造成编译失败。接口的方法默认实现为了解决上述问题C# 为接口引入了默认接口实现允许用户为接口添加默认的方法实现。有了默认实现之后即使开发者为一个接口添加了新的方法只要提供一个默认实现就不会导致类型错误而编译失败interface IParsableT {T Parse(string text);public void Foo() { ... } }这样一来IParsableT 就有 Foo 方法了。不过要注意的是这个 Foo 方法不同于 Parse 方法Foo 如果没有被实现则不是虚方法也就是说它的实现在接口上而不会带到没有实现这个接口的类上。如果不给类实现 Foo 无法调用的除非把类型强制转换到接口上class IntFactory : IParsableint {public int Parse(string text) { ... } }interface IParsableT {T Parse(string text);public void Foo() { ... } }var parser new IntFactory(); parser.Foo(); // 错误 ((IParsableint)parser).Foo(); // 没问题接口的静态方法默认实现既然接口能默认实现方法了那扩充一下让接口支持实现静态方法也是没有问题的interface IParsableT {T Parse(string text);public void Foo() { ... }public static void Bar() { ... } }不过接口中的这样的静态方法同样不是虚方法只有在接口上才能进行调用并且也不能被其他类型实现。跟类中的静态方法一样想要调用的时候只需要IParsableint.Bar();即可。你可能会好奇这个和多继承有什么区别C# 中接口的默认实现都是非虚的并且还无法访问字段和不公开的方法只当作一个向前兼容的设施即可因此不必担心 C 的多继承问题会出现在 C# 里面。接口的虚静态方法将接口的静态方法作为非虚方法显然有一定的局限性只能在接口上调用静态方法却不能在实现了接口的类上调用实用性不高类没法重写接口静态方法的实现进而没法用来抽象运算符重载和各类工厂方法因此从 C# 10 开始引入了抽象/虚静态方法的概念允许接口定义抽象静态方法在 C# 11 中则会允许定义虚静态方法。这样一来之前的 IParsableT 的例子中我们就可以改成interface IParsableT {abstract static T Parse(string text); }然后我们可以对该接口进行实现struct Int32 : IParsableInt32 {public static int Parse(string text) { ... } }如此一来我们组合泛型约束诞生了一种全新的设计模式完全代替了原来需要创建工厂实例的工厂模式T CreateInstanceT(string text) where T : IParsableT {return T.Parse(text); }原来需要专门写一个工厂类型来做的事情现在只需要一个函数就能完成同样甚至更强大的功能不仅能省掉工厂自身的分配编写起来也更加简单了并且还能用到运算符上原本的工厂模式被我们彻底扔进垃圾桶。我们还可以将各种接口组合起来应用在泛型参数上例如我们想编写一个通用的方法用来计算 a * b c但是我们不知道其类型现在只需要简单的V CalculateT, U, V(T a, U b, V c)where T : IMultiplyOperatorsT, U, Uwhere U : IAdditionOperatorsU, V, V {return a * b c; }其中 IAdditionOperators 和 IMultiplyOperators 都是 .NET 7 自带的接口三个类型参数分别是左操作数类型、右操作数类型和返回值类型并且给所有可以实现的自带类型都实现了。于是我们调用的时候只需要简单的 Calculate(1, 2, 3) 就能得到 5而如果是 Calculate(1.0, 1.5, 2.0) 则可以得到 3.5。角色和扩展至此接口自身的演进就已经完成了。接下来就是 C# 的下一步计划改进类型系统的扩展性。下面的东西预计会在接下来的几年C# 12 或者之后到来。C# 此前一直是一门面向对象语言因此扩展性当然可以通过继承和多态来做到但是这么做有很大的问题继承理论本身的问题例如根据继承原则正方形类型继承自长方形而长方形又继承自四边形但是长方形其实不需要独立的四边长度、正方形也不存在长宽的说法这造成了实现上的冗余和定义上的不准确对类而言只有单继承没法将多个父类组合起来继承到自类上与值类型不兼容因为值类型不支持继承对接口而言虽然类型可以实现多个接口但是如果要为一个类型添加新的接口则需要修改类型原来的定义而无法进行扩展最初为了支持给类型扩展新的方法C# 引入了扩展方法功能满足了大多数情况的使用但是局限性很大扩展方法只能是静态方法无法访问被扩展类型内部的私有成员扩展方法不支持索引器也不支持属性更不支持运算符社区中也一直存在不少意见希望能让 C# 支持扩展一切C# 8 的时候官方还实现了这个功能但是最终在发布之前砍掉了。为什么因为有了更好和更通用的做法。既然我们已经有了以上对接口的改进我们何必再去给一个局限性很大的扩展方法缝缝补补呢因此角色和扩展诞生了。在这个模式里接口将成为核心同时彻底抛弃了继承。接口由于自身的特点在 C# 中也天然成为了 Rust 中 dyn trait 以及 Haskell 中 type class 的等价物。注意以下的东西目前都处于设计阶段因此下述内容只是对目前设计的介绍最终的设计和实现可能会随着对相关特性的进一步讨论而发生变化但是总体方向不会变。角色一个角色在 C# 中可以采用如下方式定义role NameT : UnderlyingType, Interface, ... where T : Constraint这样一来如果我们想给一个已有的类型 Foo 实现一个有着接口 IBar 的角色我们就可以这么写role Bar : Foo, IBar { ... }这样我们就创建了一个角色 Bar这个 Bar 则只实现了 IBar而不会暴露 Foo 中的其他成员。且不同于继承Foo 和 Bar 本质上是同一个类型只是拥有着不同的角色他们之前可以相互转换。举一些现实的例子假设我们有一个接口 IPersoninterface IPerson {int Id { get; }string Name { get; }int Age { get; } }然后我们有一个类型 Data 使用字典存储了很多数据并且 Data 自身具有一个 Idclass Data {public int Id { get; }public Dictionarystring, string Values { get; } ...; }那我们就可以给 Data 创建一个 Person 的角色role Person : Data, IPerson {public string Name this.Values[name];public int Age int.Parse(this.Values[age]); }其中无需实现 Id因为它已经在 Data 中包含了。最终这个 Person 就是一个只实现了 IPerson 的 Data它只暴露了 Id、Name 和 Age 属性而不会暴露来自 Data 的 Values 属性。以及它可以被传到任何接受 Person、Data 或者 IPerson 的地方。我们还可以组合多个接口来创建这样的角色例如interface IHasAge {int Age { get; } }interface IHasName {string Name { get; } }role Person : Data, IHasAge, IHasName {// ... }这样我们把 IPerson 拆成了 IHasAge 和 IHasName 的组合。另外在不实现接口的情况下角色也可以用来作为类型的轻量级封装role Person : Data {public string Name this.Values[name];public int Age int.Parse(this.Values[age]); }如此一来Person 将成为一种提供以“人”的方式访问 Data 的方法的类型。可以说角色就是对同一个“data”的不同的“view”一个类型的所有角色和它自身都是同样的类型在本质上和继承是完全不同的与其他语言的概念类比的话角色就等同于 concepts这也意味着 C# 向 structural typing 迈出了一大步。扩展有了角色之后为了解决扩展性的问题C# 将会引入扩展。有时候我们不想通过角色来访问一个对象里的东西我们可以直接在外部扩展已有的类型。extension DataExtension : Data {public string Name this.Values[name];public string ToJson() { ... } }这样Data 类型就有了名为 Name 的属性和 ToJson 的方法可以直接调用。除了属性和方法之外扩展一个索引器自然也不在话下。其中的 ToJson 类似以前的扩展方法不过如此一来以前 C# 的扩展方法特性已经彻底被新的扩展特性取代而且是上位替代功能性和灵活性上远超原来的扩展方法。我们还可以给类型扩展实现接口extension DataExtension : Data, IHasName {public string Name this.Values[name]; }这样一来Data 就实现了 IHasName可以传递到任何接受 IHasName 的地方。甚至借助接口的虚静态方法和泛型我们可以给所有的整数类型扩展一个遍历器用来按字节遍历底层的表示extension ByteEnumeratorT : T, IEnumerablebyte where T : unmanaged, IShiftOperatorsT, T {public IEnumeratorbyte GetEnumerator(){for (var i sizeof(T); i 0; i--){yield return unchecked((byte)this ((i - 1) * 8));}} }foreach (var b in 11223344556677L) {Console.WriteLine(b); }配合接口的静态方法我们甚至能给已有的类型扩展实现运算符extension MyExtension : Foo, IAdditionOperatorsFoo, Foo, Foo {public static Foo operator(Foo left, Foo right) { ... } }var foo1 new Foo(...); var foo2 new Foo(...); var result foo1 foo2;总结C# 从 8 版本开始逐渐开始对接口进行操刀最终的目的其实就是为了实现角色和扩展改善类型系统的扩展性。到了 C# 11C# 对接口部分的改造已经全部完成接下来就是角色和扩展了。当然目前还为时尚早具体的设计和实现也可能会变化。最终借助接口、泛型、角色和扩展C# 的类型系统将拥有等同于 Haskell 的 type class 那样的强大表达力和扩展性。而且由于是静态类型从头到尾都不需要担心任何的类型安全问题。也可以预想到随着这些特性的推出将会有不少已有的设计模式因为有了更好的做法而被取代和淘汰。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/92034.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

重点学科网站建设dw怎么做秋季运动会网站

题意: 一颗n个点的树,问其中两点之间的边上数的和加起来是3的倍数的点对有多少个? 输出这样的点对所占比例 题解: 树形dp求解 因为是求长度为3的倍数,模3的结果只有0/1/2,我们可以单独考虑作为一维。 设…

网站建设管理标准重庆招聘网站哪个好

1、MySQL卸载: (通过yum命令卸载之前安装的mysql, find命令找到mysql文件,再用rm –rf 强制删除/var/lib/mysql) 2、MySQL安装: (使用yum命令安装mysql,安装完成后启动数据库&#x…

免费建立网站教程海纳企业网站建设

题目: 如果一个字符串str,把字符串str前面任意的部分挪到后面形成的字符串叫做str的旋转词。比如str="12345",str的旋转词有"12345"、"23451"、"34512"、"45123"、和"51234"。给定两个字符串a和b,请判断a和b…

突唯阿 领先的响应式网站建设平台东莞专业做淘宝网站建设

目录项目结构国际化curd操作404页面拦截器地址: https://github.com/sevenyoungairye/spring-boot-study员工管理员系统,页面用html thymeleaf模板数据库用的是map集合,没用真实的数据库项目结构 国际化 默认中文 中文,英文切换…

杭州哪家做网站程序员接单网站

647. 回文子串 动态规划解决的经典题目,如果没接触过的话,别硬想 直接看题解。 代码随想录 516.最长回文子序列 647. 回文子串,求的是回文子串,而本题要求的是回文子序列, 大家要搞清楚两者之间的区别。 代码随想…

福海网站制作嘉定个人网站建设

观察者模式&#xff1a; 书中通过小菜描述同事在公司看股票行情&#xff0c;并请求前台帮忙在老板回来时提醒同事&#xff0c;引出需求。将前台通知同事老板回来的事写成程序。未用模式实现&#xff1a; 1 //前台类2 public class Secretary {3 private List<StockObser…

网页模板免费下载网站蚌埠高端网站建设

System.Data虽然不引人关注&#xff0c;但在.NET中&#xff0c;System.Data对于各种关系数据库的连接是非常重要的。System.Data也被称为ADO.NET&#xff0c;其前身是ActiveX Data Objects。System.Data提供了通过的框架&#xff0c;在她的基础上.NET数据驱动应用可以被构建。这…

网站弹屏广告怎么做潍坊高级网站建设推广

假设工程根目录为 d:/Project/ 然后在 d:/Project/a/b/c/d/file.py 里使用 os.getcwd() 方法获取的是 d:/Project/a/b/c/d 现在我想获取 d:/Project 怎么做? ------------------------------------分割线--------------------------------- 谢谢大家的热情回答,都怪我没有将问…

网站开发需要有登陆界面的网站微信群二维码大全网站

2019.12.31 天气&#xff1a;晴 地点&#xff1a;杭州 今天是2019年的最后一天&#xff0c;就用这篇博客来记录一下这一年的历程吧。 时间很快&#xff0c;它从指缝中悄悄划过的时候&#xff0c;我们好似毫无感觉&#xff0c;突然又一年就过去了&#xff0c;大学四年的生活也随…

广西网站建设推荐哪些网站国内打不开

datePicker日期控件是很常用的控件&#xff0c;可以使用 start &#xff0c; depth来控制取值的范围。 start &#xff0c;depth可以选择的参数有month&#xff0c;year&#xff0c;decade &#xff0c;century 。 如何要只选择年&#xff1a;我们要用参数 decade &#xff0c;…

外贸营销型网站建设平台网站做视频流量赚钱吗

1 你为什么不喜欢拍照片&#xff08;素材来源网络&#xff0c;侵删&#xff09;▼2 当登记处挂起横幅▼3 这几天老是犯的错误▼4 在图书馆收获的爱情&#xff08;素材来源网络&#xff0c;侵删&#xff09;▼5 当老师用键盘讲课&#xff08;素材来源网络&#xff0c;侵删&a…

网站首页轮播图片浙江理工大学网站设计与建设

1. 如果要判断数组中是否存在某个元素的话很好判断&#xff0c;直接用数组的indexOf方法就好&#xff0c;存在返回当前索引不存在返回-1 var arr[1,2,3,4] arr.indexOf(3) // 2 arr.indexOf(5) // -1 2. 要只是判断的话是可以遍历后判断对象的属性是否相同的&#xff0c;像这种…

公司建网站多少钱一年关于二手书的网站开发ppt

结构Hive 是建立在hadoop上的数据仓库架构,它提供了一系列的工具,可以进行数据提取转换加载(这个过程叫做ETL),这是一种可以存储,查询和分析存储在hadoop中的大规模数据的机制.Hive定义了简单的类SQL查询语句 成为hql,他允许数据SQL的用户查询数据.同时 这个语言也允许数据mapr…

网站推广哪个好温州seo网站推广

​最近一直在做AI大模型上车的战略企划工作&#xff0c;听了好多供应商的宣讲&#xff0c;自己也查阅了大量书籍、资料。信息输入呈现爆炸性增长&#xff0c;受限于专业知识水平&#xff0c;仅能在应用层面上有所思考。纯个人观点&#xff0c;仅供参考。 车自古以来都是移动工…

网站投注员怎么做苏州建设交通

一、定义和结构 作用&#xff1a;捕获同步执行代码下的异常错误 在没有使用try...catch的情况下&#xff0c;同步代码执行遇到异常会报错&#xff0c;并中断后续代码执行&#xff1b; 在使用try...catch的情况下&#xff0c;同步代码执行遇到异常会抛出异常&#xff0c;并继续…

做网站全体教程小程序代理与加盟

int[] a new int[10];int[] a new int[]{元素1&#xff0c;元素2};int[] a {元素1&#xff0c;元素2};

建设银行网站修改密码哪些网站可以做商家

近期&#xff0c;受邀担任两个国际学术会议的Special session共同主席及程序委员会成员&#xff08;TPC member&#xff09;&#xff0c;欢迎广大学界同行踊跃投稿&#xff0c;分享最新研究成果。期待这个夏天能够在夏威夷檀香山或者加利福尼亚圣荷西与各位学者深入交流。 SERA…

网站搬家后出错免费网站可以做cpa

一 Process对象的join方法 在主进程运行过程中&#xff0c;如果想并发地执行其它的任务&#xff0c;我们可以开启子进程&#xff0c;此时主进程的任务与子进程的任务分两种情况&#xff1a; 情况一&#xff1a;在主进程的任务与子进程的任务彼此独立的情况下&#xff0c;主进程…

网站开发技术发展历程wordpress导入网站

假设我们有一个称为nums和另一个数字k的不同数字的列表&#xff0c;我们必须找到总计为k的不同组合的数量。您可以在创建组合时重复使用数字。因此&#xff0c;如果输入像nums [2&#xff0c;4&#xff0c;5] k 4&#xff0c;那么输出将是2&#xff0c;因为我们可以将两个这样…

做网站赚钱交税昆明网站建设知名企业

从Eumetsat批量下载哨兵数据等各种数据 那些最好的程序员不是为了得到更高的薪水或者得到公众的仰慕而编程&#xff0c;他们只是觉得这是一件有趣的事情&#xff01; 批量下载Sentinel数据脚本2023 从Eumetsat批量下载哨兵数据等各种数据&#x1f33f;前言&#x1f340;脚本构成…