C#中常用的索引器

之前了解过索引器,当时还把索引器和属性给记混了, 以为索引器就是属性,下面写下索引器和属性的区别,以及怎么使用索引器

先说明一点,这里的索引器和数据库中的索引不一样,虽然都是找元素。

索引器和属性的区别:

  1. 属性是以名称来标识,而索引器是以函数的形式来标识(但是索引器不能完全理解为函数);
  2. 索引器可以被重载,而属性没有重载这一说法;
  3. 索引器不能声明为static,而属性可以;

还有一点就是索引很像数组,它允许一个对象可以像数组一样被中括号 [] 索引,但是和数组有区别,具体有:

  1. 数组的角标只能是数字,而索引器的角标可以是数字也可以是引用类型;
  2. 数组是一个变量,而索引器可以理解为一个函数;

我在代码中很少自己定义索引器,但是我却经常在用它,那是因为系统自定义了很多索引器,比如 ADO.NET 中对于 DataTable 和 DataRow 等类的各种遍历,查找,很多地方就是用的索引器,比如下面这篇博客中的代码就使用了很多系统自定义的索引器:

DataTable的AcceptChanges()方法和DataRow的RowState属性 (其中索引器的使用都以及注明,)

那我们如何自定索引器? 回到这篇博客第一句话,我曾经把索引器和属性弄混过,那就说明他俩很像,看下代码看是不是很像:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Dynamic;
//这里的代码时参照自http://www.cnblogs.com/ArmyShen/archive/2012/08/27/2659405.html的代码片段
namespace ConsoleApplicationTest
{

    public class IndexerClass
    {
        private string[] name = new string[2];

        //索引器必须以this关键字定义,其实这个this就是类实例化之后的对象
        public string this[int index]
        {
            //实现索引器的get方法
            get
            {
                if (index < 2)
                {
                    return name[index];
                }
                return null;
            }

            //实现索引器的set方法
            set
            {
                if (index < 2)
                {
                    name[index] = value;
                }
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            //索引器的使用
            IndexerClass Indexer = new IndexerClass();
            //“=”号右边对索引器赋值,其实就是调用其set方法
            Indexer[0] = "张三";
            Indexer[1] = "李四";
            //输出索引器的值,其实就是调用其get方法
            Console.WriteLine(Indexer[0]);
            Console.WriteLine(Indexer[1]);
        }
    }
}

乍一眼看上去,感觉和属性一样了, 但是索引器多了的名称和属性的名称不一样,而且多了 this 关键字,看到这里的 this 的特殊用法又让我想到了扩展方法中的 this的特殊位置。

以字符串为角标, 这点就和数组不一样了:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Dynamic;
using System.Collections;
//这里的代码时参照自http://www.cnblogs.com/ArmyShen/archive/2012/08/27/2659405.html的代码片段
namespace ConsoleApplicationTest
{

    public class IndexerClass
    {
        //用string作为索引器下标的时候,要用Hashtable
        private Hashtable name = new Hashtable();

        //索引器必须以this关键字定义,其实这个this就是类实例化之后的对象
        public string this[string index]
        {
            get { return name[index].ToString(); }
            set { name.Add(index, value); }

        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            IndexerClass Indexer = new IndexerClass();
            Indexer["A0001"] = "张三";
            Indexer["A0002"] = "李四";
            Console.WriteLine(Indexer["A0001"]);
            Console.WriteLine(Indexer["A0002"]);
        }
    }
}

索引器的重载,这点就是属性的不同:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Dynamic;
using System.Collections;
//这里的代码时参照自http://www.cnblogs.com/ArmyShen/archive/2012/08/27/2659405.html的代码片段
namespace ConsoleApplicationTest
{

    public class IndexerClass
    {
        private Hashtable name = new Hashtable();

        //1:通过key存取Values
        public string this[int index]
        {
            get { return name[index].ToString(); }
            set { name.Add(index, value); }
        }

        //2:通过Values存取key
        public int this[string aName]
        {
            get
            {
                //Hashtable中实际存放的是DictionaryEntry(字典)类型,如果要遍历一个Hashtable,就需要使用到DictionaryEntry
                foreach (DictionaryEntry d in name)
                {
                    if (d.Value.ToString() == aName)
                    {
                        return Convert.ToInt32(d.Key);
                    }
                }
                return -1;
            }
            set { name.Add(value, aName); }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            IndexerClass Indexer = new IndexerClass();

            //第一种索引器的使用
            Indexer[1] = "张三";//set访问器的使用
            Indexer[2] = "李四";
            Console.WriteLine("编号为1的名字:" + Indexer[1]);//get访问器的使用
            Console.WriteLine("编号为2的名字:" + Indexer[2]);

            Console.WriteLine();
            //第二种索引器的使用
            Console.WriteLine("张三的编号是:" + Indexer["张三"]);//get访问器的使用
            Console.WriteLine("李四的编号是:" + Indexer["李四"]);
            Indexer["王五"] = 3;//set访问器的使用
            Console.WriteLine("王五的编号是:" + Indexer["王五"]);
        }
    }
}

具有多个参数的索引器:

using System;
using System.Collections;
//这里的代码时参照自http://www.cnblogs.com/ArmyShen/archive/2012/08/27/2659405.html的代码片段
namespace ConsoleApplicationTest
{
    /// <summary>
    /// 入职信息类
    /// </summary>
    public class EntrantInfo
    {
        //姓名、编号、部门
        public string Name { get; set; }
        public int Num { get; set; }
        public string Department { get; set; }
    }

    /// <summary>
    /// 声明一个类EntrantInfo的索引器
    /// </summary>
    public class IndexerForEntrantInfo
    {
        private ArrayList ArrLst;//用于存放EntrantInfo类
        public IndexerForEntrantInfo()
        {
            ArrLst = new ArrayList();
        }

        /// <summary>
        /// 声明一个索引器:以名字和编号查找存取部门信息
        /// </summary>
        /// <param name="name"></param>
        /// <param name="num"></param>
        /// <returns></returns>
        public string this[string name, int num]
        {
            get
            {
                foreach (EntrantInfo en in ArrLst)
                {
                    if (en.Name == name && en.Num == num)
                    {
                        return en.Department;
                    }
                }
                return null;
            }
            set
            {
                ArrLst.Add(new EntrantInfo()
                {
                    Name = name,
                    Num= num,
                    Department = value
                });
            }
        }

        /// <summary>
        /// 声明一个索引器:以编号查找名字和部门
        /// </summary>
        /// <param name="num"></param>
        /// <returns></returns>
        public ArrayList this[int num]
        {
            get
            {
                ArrayList temp = new ArrayList();
                foreach (EntrantInfo en in ArrLst)
                {
                    if (en.Num == num)
                    {
                        temp.Add(en);
                    }
                }
                return temp;
            }
        }
        //还可以声明多个版本的索引器...
    }

    class Program
    {
        static void Main(string[] args)
        {
            IndexerForEntrantInfo Info = new IndexerForEntrantInfo();
            //this[string name, int num]的使用
            Info["张三", 101] = "人事部";
            Info["李四", 102] = "行政部";
            Console.WriteLine(Info["张三", 101]);
            Console.WriteLine(Info["李四", 102]);

            Console.WriteLine();

            //this[int num]的使用
            foreach (EntrantInfo en in Info[102])
            {
                Console.WriteLine(en.Name);
                Console.WriteLine(en.Department);
            }
        }
    }
}
时间: 2024-10-04 22:05:36

C#中常用的索引器的相关文章

使用C#索引器轻松访问iBoxDB中的数据

使用SQL访问一个数据的操作是 select * from Table where ID=1 通过封装一般简化为类似如下的操作 DB.Find( "Table", 1); 在 iBoxDB 中借助C#索引器,操作简化到 DB["Table",1]; 一个简单但完整使用Xamarin结合iBoxDB开发Android应用的例子 var db = new DB (1, System.Environment.GetFolderPath ( System.Environme

ylbtech-LanguageSamples-Indexers(索引器)

ylbtech-Microsoft-CSharpSamples:ylbtech-LanguageSamples-Indexers(索引器) 1.A,示例(Sample) 返回顶部 “索引器”示例 本示例演示 C# 类如何声明索引器以提供对类的类似数组的访问. 安全说明 提供此代码示例是为了阐释一个概念,它并不代表最安全的编码实践,因此不应在应用程序或网站中使用此代码示例.对于因将此代码示例用于其他用途而出现的偶然或必然的损害,Microsoft 不承担任何责任. 在 Visual Studio

C#类索引器的使用

索引器提供了一种可以让类被当作数组进行访问的方式.在C#中,类索引器是通过this的属性实现的.index.ToString("D2")将index转换成一个具有两个字符宽度的字符串 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ClassIndexer { /// <summary> /// define a class cal

44. C# -- 索引器和属性

1.属性 所谓属性其实就是特殊的类成员,它实现了对私有类域的受控访问.在C#语言中有两种属性方法,其一是get,通过它可以返回私有域的值,其二是set,通过它就可以设置私有域的值.比如说,以下面的代码为例,创建学生姓名属性,控制对name字段的受控访问: using System; public class Student  {      private string name;      /// <summary>      /// 定义学生的姓名属性     /// </summar

C#基本语法复习-使用索引器

索引是使用this关键字来引入的,this关键词之前要指定返回值的类型,在后面的方括号中要指定索引器的索引使用值的类型:一个雷或节后中只能有一个索引: public bool this [int index] { get{}set{} } 接口中的索引: interface Ia{ bool this [int index]{get;set;} }

Spring Boot项目中如何定制拦截器

本文首发于个人网站:Spring Boot项目中如何定制拦截器 Servlet 过滤器属于Servlet API,和Spring关系不大.除了使用过滤器包装web请求,Spring MVC还提供HandlerInterceptor(拦截器)工具.根据文档,HandlerInterceptor的功能跟过滤器类似,但拦截器提供更精细的控制能力:在request被响应之前.request被响应之后.视图渲染之前以及request全部结束之后.我们不能通过拦截器修改request内容,但是可以通过抛出异

C# 类中索引器的使用二

索引器(Indexer)是C#引入的一个新型的类成员,它使得类中的对象可以像数组那样方便.直观的被引用.索引器非常类似于属性,但索引器可以有参数列表,且只能作用在实例对象上,而不能在类上直接作用.定义了索引器的类可以让您像访问数组一样的使用 [ ] 运算符访问类的成员.(当然高级的应用还有很多,比如说可以把数组通过索引器映射出去等等) 本文只是简单演示一下索引器的概念和基本的使用方法: 请看代码,下面是类的定义,中间包含了一个索引器定义 类的定义 public class Person { //

C#中的索引器原理

朋友们,还记得我们在C#语言开发中用到过索引器吗? 记得在获得DataGridView控件的某列值时:dgvlist.SelectedRows[0].Cells[0].Value; 记得在获得ListView控件的某列值时:listView1.SelectedItems[0].SubItems[0].Text; 记得在读取数据库记录给变量赋值时:result=dr["StudentName"].ToString(); 记得Dictionary中根据key值来获取Value值时:dic[

18._5索引器在类中的使用

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _18._5索引器在类中的使用 { class Program { public class indexText //访问类实例 { private int[] array = new int[10]; public int this[int in