C# 索引器与迭代器分部类详情

news2024/11/19 13:44:38

文章目录

  • 一、迭代器
  • 二、查看Foreach执行中间语言
  • 三、foreach实现过程总结
  • 四、实现迭代器最常用的方法
  • 五、分布类概述及其使用
  • 六、索引器概述及声明
  • 七、索引器在类中的使用
  • 八、索引器在接口中的使用
  • 九、总结


一、迭代器

1、迭代器(iterator)解决的是集合访问的问题,提供一种方法顺序访问一个集合对象中的各个元素,而不暴露对象内部标识。迭代器还有一个别名:游标(cursor)
2、foreach语句与迭代器的关系:Foreach循环语句可以用来迭代枚举的集合中的所有元素,又称foreach迭代语句
3、可枚举的: C#中,如果某个类型继承了接口IEnumerable,或者继承了泛型接口IEnumerable或者继承了泛型接口IEnumerable的任何构造类型,那么久成这个类型时可枚举的
4、常见的可枚举类型:集合,数组,字符串类String,标识动态列表的泛型类List等
在这里插入图片描述
在这里插入图片描述
5、Foreach语句可以简化C#内置迭代器的使用复杂性,编译froeach语句,会生成调用GetEnumerator和MoveNext方法以及Current属性的代码,这些方法和属性恰是C#内置迭代器所提供的。
6、ILDASM外部工具的添加方法(中间语言反汇编的工具)
方法1:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

打开新添加的外部工具:

在这里插入图片描述

方法2
在这里插入图片描述
在这里插入图片描述

二、查看Foreach执行中间语言

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
中间语言: language
ILDASM: intermediate language decompile assembly
在这里插入图片描述

三、foreach实现过程总结

foreach语句是微软提供的支持内置迭代器的语句法糖,编译foreach语句后生产的代码与使用迭代器的代码完全一致
调用GetEnumerator()方法获得迭代器——调用IEnumerator.MoveNext()——调用IEnumerator.Current()

Foreach循环迭代可枚举类型的过程:

1、通过调用IEnumerator接口和IEnumerator的引用
2、IEnuerator调用MoveNext方法
3) ①True:IEnumerator的Current属性获取对象的应用,用于foreach循环
②false 结束
4、重复2、3步知道MoveNext返回false

四、实现迭代器最常用的方法

迭代器可用于方法、属性访问器或其他代码块,使用户能够在类或结构中支持Foreach迭代,而不必实现整个IEnumerable接口,只需要一个类型化的方法GetEnumerator(),不需要处理设计模式

1、迭代器是C#可以提供的最简单的设计模式。
2、设计模式(Design pattern/behavorial pattern)是一套被反复使用、多数人知晓的、经过分类编目的、典卖设计经验总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。
3、.Net Framework有自己的IEnumerator接口,使用的迭代器的作用很明确,及可以做到不暴露集合的内部接口,又可让外部代码同名地方访问集合内部的数据。 2.1 创建迭代器最常用的方法 是对IEnumerable接口实现GetEnumerator方法创建最简单的迭代块说明:迭代器返回值类型必须为IEnumerable(迭代类成员)和IEnumerator(迭代类)一个迭代器会出现一个或者多个yield语句,与一般语句块的区别:yield return 一次返回迭代的下一个袁旭yield break 指出这个迭代的结束

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;            // 需要引用的命名空间
namespace 实现迭代器常用的方法
{
    class Program
    {
        public static IEnumerable SimpleDemo()
        {
            yield return "string1";
            yield return "string2";
            yield return "string3";
            yield break;  //运行到此处就终止了迭代
            yield return "string4";
            yield return "string5";
 
        }
        //月份迭代
        public class Months : IEnumerable        //为了使用Foreach遍历,要保证是可枚举类型的
        {
            string[] month = { "Jan", "Feb", "Mar", "Apr", "May", "June", "July", "Aug", "Nov", "Dec" };
            public IEnumerator GetEnumerator()
            {
                for(int i=0;i<month.Length;i++)
                {
                    yield return month[i];
 
                }
            }
        }
        static void Main(string[] args)
        {
            foreach (string item in SimpleDemo())
            {
                Console.WriteLine(item);
            }
            Months mon = new Months();
            foreach(string m in mon)
            {
                Console.WriteLine(m);
            }
            Console.ReadKey();
 
        }
    }
}

五、分布类概述及其使用

分布类定义: 将类的定义拆分到两个或多个资源文件中。每个源文件包含类定义的一部分,编译应用程序时将把所有部分组合起来,这就是分布类。

应用场合(partial):
1、处理大型项目时,使一个类分布于多个独立文件中,可以让多位程序员同时对该类进行处理;
2、使用自动生成的源时,无需重新创建源文件便可将代码添加到类中。
vs在创建windows窗体和web服务包装代码等时都是用此方法。开发人员无须编译vs所创建的文件,即可创建使用这些类的代码。

实现过程:

1、通过多个部分来定义一个类
2、partial关键字:必须直接放在class的前面
3、分部类声明的每个部分都必须包含partial修饰符,并且器声明必须与其他部分位于同一命名空间。
4、partial修饰符说明在其他位置可能还有同一个类型声明的其他部分。但是这些其他部分并非必须存在:如果只有一个类型声明,包含partial修饰符也是有效的。
5、当分部类声明指定了可访问性(借助访问修饰符:public、protected、internal private)时,它必须与其他部分所指定的可访问性一致。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace _3_分部类
{
    //利用分部类实现阶乘与幂指数运算
    partial class arithmetic    //阶乘
    {
        public int factorial(int num)
        {
            int factorialval = 1;
            for(int i = num; i>0;i--)
            {
                factorialval *= i;
            }
            return factorialval;
        }
    }
 
    partial class arithmetic //幂指数运算
    {
        public int power(int num, int index)
        {
            int result = 1;
            for (int i = 0; i < index; i++)
            {
                result *= num;
            }
 
            return result; 
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            arithmetic a = new arithmetic();
            int num = 5;
            Console.WriteLine("调用分部类的第一部分——阶乘计算结果:{0}", a.factorial(num));
            int index = 3;
            Console.WriteLine("调用分部类的第二部分——幂指函数计算结果:{0}", a.power(num, index));
            Console.ReadKey();
        }
    }
}

注意事项 :

1、分部类时,同一个类型各个部分的所有分部类类型定义都必须使用partial进行修饰,必须具有相同的可访问性。
2、同一个类型的各个部分的所有分部类型定义都必须在同一程序集合同一模块中进行定义。分部类定义不能跨越多个模块。
3、使用partial关键字表明可在命名空间内定义该类、结构或接口的其他部分,各个部分可以指定不同的基接口,最终类型将实现,所有分部声明所列出的全部接口。

六、索引器概述及声明

可以通过小标访问数组中的元素的方式就是索引器
索引器允许类或结构的实例按照与数组相同的方式进行索引。索引器的声明和属性的声明非常相似,不同的是他们的访问器采用参数——索引器的声明除了包括索引关键字(index)的声明外,还包括this关键字。使得向数组那样对对象使用下标,并提供了通过索引方式方便第访问类的数据信息的方法。(属性的作用就是保护字段,对字段的取值和赋值进行限定)

虚拟索引器:virtual
外部索引器:extern 因为外部索引器声明不提供任何实际的实现,所以他的每个访问器生摩纳哥都由一个分号组成。
抽象索引器:abstract 当要定义为抽象索引器时,必须提供空的get和set,必须在抽象类中声明抽象索引器

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _4_索引器概述及声明
{
    //属性声明
    public class Clerk
    {
        private string name;   //字段声明,专供类内部使用,所以声明为私有的
        public string Name     //属性为外部事务,可以供其他类进行交流使用,所以声明为公共的
        {
            get { return name; }
            set { name = value; }
        }
        private char gender;
        public char Gender
        {
            get
            {
                if (gender != '男' && gender != '女') gender = '男';
                return gender;
            }
            set
            {
                gender = value;
            }
        }
 
        //索引器声明1
        //private int[] myint = new int[10];
        //public int this[int index]
        //{
        //    get { return myint[index]; }   //单独存在为只读
        //    set { myint[index] = value; }  //单独存在为只写  ,两个同时存在为读写
        //}
 
 
        //声明一个虚拟的索引器
        //private int[] myint2 = new int[10];
        //public virtual int this[int index2]
        //{
        //    get { return myint2[index2]; }
        //    set { myint2[index2] = value; }
        //}
 
        // 声明一个外部索引器
        public extern int this[int index]
        { get; set; }
 
    }
    // 抽象索引器声明
    abstract class indexEaxmple
    {
        public abstract int this[int index]
        {
            get;
            set;
        }
    }
        class Program
        {
            static void Main(string[] args)
            {
            }
        }
    }

七、索引器在类中的使用

索引器允许用户按照处理数组的方式索引类,访问时有两种形式
使用索引器可直接访问类实例:将数组声明为public成员并直接访问它的成员;
实例:1、访问类实例(容量为10的整型数组为例)2、访问类成员(以星期演示)

using System;
namespace _5_索引器在类中的使用
{
    public class indexText //访问类的实例
    {
        private int[] array = new int[10];
        public int this[int index]
        {
            get
            {
                if (index < 0 || index > 10) return 0;
                else return array[index];
            }
            set
            {
                if (index >= 0 && index < 10) array[index] = value;
            }
        }
    }
    public class weekIndex //访问类成员
    {
        string[] week = { "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日" };
        private int getDay(string weekText)
        {
            int i = 0;
            foreach(string day in week)
            {
                if (day == weekText) return i+1;
                i++;
            }
            return -1;
        }
        public int this[string week]
        {
            get { return getDay(week); }
 
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("访问类实例的结果");
            indexText Arr = new indexText();
            Arr[-5] = 5;
            Arr[0] = 15;
            Arr[2] = 60;
            Arr[11] = 65;
            Console.WriteLine("Arr[-5]={0}", Arr[-5]);
            Console.WriteLine("Arr[0]={0}", Arr[0]);
            Console.WriteLine("Arr[1]={0}", Arr[1]);
            Console.WriteLine("Arr[2]={0}", Arr[2]);
            Console.WriteLine("Arr[11]={0}", Arr[11]);
            Console.WriteLine("访问累成员结果");
            weekIndex we = new weekIndex();
 
            Console.WriteLine(we["星期三"]);
            Console.WriteLine(we["星期四"]);
            Console.WriteLine(we["星期八"]);
            Console.WriteLine(we["星期0"]);
 
            Console.ReadKey();
        }
    }
}

八、索引器在接口中的使用

索引器可以作为接口成员来声明,单接口中的索引器声明不包括任何访问修饰符,这是因为接口不包括任何编程程序语句,所以get和set访问器没有程序主题,因此,访问索引器的用途是指示索引器时读写、只读还是只写

using System;
namespace _6_索引器在接口中的使用
{
    public interface iTextIndex
    {
        int this[int index]
        {
            get;
            set;
        }
    }
    class indexText:iTextIndex
    {
        // 演示容量为10的数组,对实例成员的访问
 
        private int[] array = new int[10];
        public int this[int index]
        {
            get
            {
                if (index < 0 || index >= 10) return 0;
                else return array[index];
            }
            set
            {
                if (index > 0 && index < 10) array[index] = value;
            }
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            indexText Arr = new indexText();
            Arr[-1] = 5;
            Arr[4] = 10;
            Arr[9] = 20;
            Arr[14] = 30;
            for(int i=-1;i<15;i=i+5)
            {
                Console.WriteLine("Arr[{0}]={1}", i, Arr[i]);
 
            }
            Console.ReadKey();
        }
    }
}

九、总结

索引器实现QQ状态的访问,利用类成员进行访问,得出QQ状态对应的索引值

using System;
namespace 本章小结及任务实施
{
    public class QQStateIndex
    {
        string [] qqState = { "在线", "离线", "忙碌", "Q我", "隐身" };
        private int getState(string stateText)
        {
            int i= 0;
            foreach(string stateString in qqState)
            {
                if (stateString == stateText) return i;
                i++;
            }
            return -1;
        }
        public int this[string stateString]
        {
            get { return getState(stateString); }
 
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            QQStateIndex qs = new QQStateIndex();
            Console.WriteLine(qs["在线"]);
            Console.WriteLine(qs["忙碌"]);
            Console.WriteLine(qs["睡眠"]);
            Console.ReadKey();
        }
    }
}

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

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

相关文章

饮食中的隐形杀手,该如何避免?

塑料发明至今&#xff0c;口碑经历了过山车式的翻转。 上世纪&#xff0c;塑料曾被誉为20世纪最伟大的发明之一&#xff0c;围绕着塑料科学研究诞生出了好几位诺贝尔奖得主。 1953年&#xff0c;因在高分子化学方面的贡献&#xff0c;德国科学施陶丁格获诺贝尔化学奖&#xf…

Stable Diffusion 秋叶整合包v4.7 :解压即用,快速入门AI绘画

Stable Diffusion秋叶整合包&#xff0c;超简单一键安装Stable Diffusion&#xff0c;无任何使用门槛&#xff0c;完全免费使用&#xff0c;支持Nvdia全系列显卡&#xff0c;来自B站up秋葉aaaki&#xff0c;近期发布了Stable Diffusion整合包v4版本&#xff0c;一键在本地部署S…

中国各区域人口密度可视化图

原文链接https://mp.weixin.qq.com/s?__bizMzUyNzczMTI4Mg&mid2247674303&idx1&sn830304f80a0429406c4a5e38dc7750ec&chksmfa777682cd00ff9434e4660bb52ab2bf19913b6732083de061664401a9ac0fa46581cd9e5e86&token1445576002&langzh_CN&scene21#we…

【TB作品】MSP430G2553,单片机,口袋板,流量积算仪设计

题9 流量积算仪设计 某型流量计精度为0.1%, 满刻度值为4L/s&#xff0c;流量计输出为4—20 mA。 设计基于MSP430及VFC32的流量积算仪。 具体要求 (1) 积算仪满刻度10000 L&#xff0c;精度0.1 L; 计满10000 L&#xff0c;自动归零并通过串口&#xff08;RS232&#xff09;向上位…

Llama 3 大型语言模型到底是如何炼成的?

Meta 在今年 4 月开源了 Llama 3 大型语言模型&#xff0c;这是 Meta&#xff0c;也是整个行业迄今为止功能最强大的开源 LLM。 那么 Meta 是如何训练 Llama 3 大型语言模型的&#xff0c;又在训练过程中遇到了什么问题&#xff0c;提出了什么新的解决方案呢&#xff1f;近日&…

【Nodejs 日志库 】

总结了几个比较好用的Nodejs日志库&#xff0c;我认为一个 合格的日志库 需要 支持多种传输&#xff0c;如文件、控制台、HTTP 等。可定制的日志级别和格式。异步日志记录。 根据上述的需求&#xff0c;挑选出 几款比较好用的日志库&#xff0c; 1. Winston&#xff08;Gith…

如何灵活运用keil工具进行问题分析(2)— 定位FreeRTOS的栈溢出导致hardfault问题

前言 &#xff08;1&#xff09;如果有嵌入式企业需要招聘湖南区域日常实习生&#xff0c;任何区域的暑假Linux驱动实习岗位&#xff0c;可C站直接私聊&#xff0c;或者邮件&#xff1a;zhangyixu02gmail.com&#xff0c;此消息至2025年1月1日前均有效 &#xff08;2&#xff0…

防火墙中的NAT

防火墙的NAT NAT分类 源NAT 基于源IP地址进行转换。 我们之前接触过的静态NAT&#xff0c;动态NAT&#xff0c;NAPT都属于源NAT&#xff0c;都是针对源IP地址进行转换的。源NAT主要目的是为了保证内网用户可以访问公网。 先执行安全策略&#xff0c;后执行NAT 目标NAT 基于…

【归档】工作流审批初体验

title: 工作流审批初体验 typora-root-url: 工作流审批初体验 date: 2023-05-09 17:00:39 tags: 项目插件 文章目录 参考文档工作流审批 flowable设置工作流模型绑定用户 设计表单绑定表单 用户发起流程上传查看流程范围流程可视化 请假流程与OA流程子集关系 参考文档 迁移文…

Termius for Mac/Win:跨平台多协议远程管理利器

Termius for Mac/Win是一款备受瞩目的跨平台多协议远程管理软件&#xff0c;以其卓越的性能、丰富的功能和便捷的操作体验&#xff0c;赢得了广大用户的青睐。无论是在企业IT管理、系统维护&#xff0c;还是个人远程连接、文件传输等方面&#xff0c;Termius都展现出了出色的实…

webpack5入门,根据官方文档简单学习,简单总结

c.**loader加载器&#xff1a;**webpack 只能理解 JS文件和 JSON 文件&#xff0c;loader 让 webpack 能够去处理其他类型的文件&#xff0c;并将它们转换为有效 模块&#xff0c;以供应用程序使用&#xff0c;以及被添加到依赖图中。&#xff08;比如css&#xff0c;less&…

从理论到实践掌握UML

统一建模语言&#xff08;UML&#xff09;是软件工程师用来设计软件系统的一种工具&#xff0c;就像是一套图形化的说明书。它让开发团队能够以图形化的方式来理解、设计和开发软件系统&#xff0c;比起用文字来描述&#xff0c;更加直观易懂。本文通过UML实例化的理论和实践相…

小米HyperOS 澎湃os机型免答题 免社区等级 秒接bl锁操作步骤解析【二】

前面两期博文; 小米HyperOS 澎湃os机型免答题 免社区等级 秒接bl锁操作步骤解析 小米机型解锁bl 绕过社区等级5才可以解锁的限制的教程_没有五级社区怎么解锁bl-CSDN博客 小米对米粉解锁bl是越来越苛刻了。目前社区等级 答题 审核等等步骤越来越繁琐。而且通过率很低。知名开…

04 Pytorch tensor

一&#xff1a;老版本的 variable 二&#xff1a;新版 tensor 曾经&#xff1a;求导相关 如今&#xff1a;数据相关 –dtype: 张量的数据类型&#xff0c;三大类&#xff0c;共9种。torch.FloatTensor, torch.cuda.FloatTensor –shape: 张量的形状。如&#xff1a;&#x…

PTP简介及Linux phy ptp驱动实现

1、PTP简介 PTP(precision time protocol)精确时间协议&#xff0c;是一种时间同步的协议&#xff0c;对应 IEEE 1588 标准&#xff0c;是基于网络数据包的一种时间同步协议&#xff0c;1588v2的同步精度可以达到ns级&#xff0c;但1588协议对硬件有依赖。 2、PTP原理 时间同…

手把手!从头构建LLaMA3大模型(Python)

1. 前期准备 让我们先来想一想大概需要做什么。 首先是模型架构的选择。原工作用的是 GPT Neo 架构&#xff08;可以看他们的 config&#xff09;&#xff0c;这个算是很老的模型了&#xff0c;最初是 EleutherAI 用来复现追踪 GPT-3 的工作的&#xff0c;现在用的也比较少了…

java入门1.4.0

前言&#xff1a; 在1.4.0版本中&#xff0c;更新了对语言三大要素的理解 红字为更新&#xff0c;绿字为迭代 这时我们目前拥有的知识 正片&#xff1a; 有了这些内容&#xff0c;我们就可以顺利进入到Spring Boot阶段了 Q&#xff1a;有人就会问&#xff0c;面向对象的特性…

瑞典农业科学大学《Nature Geoscience》(IF=18)!揭示北方森林碳汇对干旱的响应机制!

本文首发于“生态学者”微信公众号&#xff01; 北方森林覆盖了地球陆地面积的11%&#xff0c;储存了全球陆地碳储量的约三分之一。因此&#xff0c;它们被认为是减缓气候变化政策的一个重要因素。然而&#xff0c;环极寒带地区是气候变化速度最快的地区。这包括更频繁和更严重…

谷粒商城实战(042集群学习-mysql集群-主从同步)

Java项目《谷粒商城》架构师级Java项目实战&#xff0c;对标阿里P6-P7&#xff0c;全网最强 总时长 104:45:00 共408P 此文章包含第361p-第p363的内容 集群 集群的基础形式 MySQL集群 MMM机制 这里使用了vip虚拟ip方式&#xff08;如192.168.0.101&#xff0c;192.168.0.102&…

换位置(C++)

问题描述 体育课上&#xff0c;有一个班级的同学站成了一队&#xff0c;体育老师请最高的和最矮的两位同学调换一下位置&#xff0c;其余的同学不要动&#xff0c;请编程实现&#xff01;&#xff08;假设所有人的高矮都是不一样的&#xff09; 输入 第一行有一个整数 &…