C#中常用的索引器

来源:http://www.cnblogs.com/daimajun/archive/2017/05/06/6819081.html
-Advertisement-
Play Games

之前瞭解過索引器,當時還把索引器和屬性給記混了, 以為索引器就是屬性,下麵寫下索引器和屬性的區別,以及怎麼使用索引器 先說明一點,這裡的索引器和資料庫中的索引不一樣,雖然都是找元素。 索引器和屬性的區別: 屬性是以名稱來標識,而索引器是以函數的形式來標識(但是索引器不能完全理解為函數); 索引器可以... ...


之前瞭解過索引器,當時還把索引器和屬性給記混了, 以為索引器就是屬性,下麵寫下索引器和屬性的區別,以及怎麼使用索引器

先說明一點,這裡的索引器和資料庫中的索引不一樣,雖然都是找元素。

索引器和屬性的區別:

  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);
            }
        }
    }
}

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • "沒有時間了!" 本次學習mongoDB,參考瞭如下文章: Using MongoDB with ASP.NET Core – Part II (Implementation) 來自 MongoDB學習筆記(二) 通過samus驅動實現基本數據操作 來自 略去如何安裝和調試MongoBD,可參見上述... ...
  • 我遇到問題產生的原因:資料庫表的某個欄位為不能為空。在修改實體屬性的時候,實體對應的表中不能為空的欄位為null。 詳情: 資料庫: c #: 錯誤代碼: 正確代碼: ...
  • 最近由於工作需要,做一個C#的簡單程式。學習了一些基礎東西先記下來。 主要有: 1.生成初始框架 2.打亂順序 3.游戲部分,點擊按鈕後與空白部分交換的只是Text和Visible部分 ...
  • 前端應用程式 ASP.NET Zero包含可以作為您的公共網站或應用程式著陸頁的起點的前端頁面。首次運行項目時,您會看到主頁如下所示: 這裡有兩頁:主頁和關於。這些頁面的內容只是占位符和演示目的。您可以根據需要完全刪除內容並構建頁面。此外,你應該改變的標誌與貴公司的標誌。 請參閱 metronic前 ...
  • 後端應用程式 這是用戶名和密碼輸入的實際應用程式。您將主要在此應用程式上添加您的業務需求。 應用文件夾 後端應用程式預設內置在專用區域,名為“ App ”,但可以在創建解決方案時確定。因此,所有控制器,視圖和模型都位於 Areas / App文件夾下。此外,相關腳本和樣式文件位於wwwroot / ...
  • ASP.NET Zero--開髮指南(Lyhcee 譯) 01. 前期介紹 02. 前期要求 03. 解決方案結構(層) 04. 前端應用程式 05. 後端應用程式 06.WEB.HOST應用程式 07.Migration控制台應用程式 08. 基礎設施 09. 基於令牌的認證&SWAGGER UI ...
  • 一、前言 我心中的插件系統應該是像Nop那樣(更牛逼的如Orchard,OSGI.NET),每個插件模塊不只是一堆實現了某個業務介面的dll,然後採用反射或IOC技術來調用,而是一個完整的mvc小應用,我可以在後臺控制插件的安裝和禁用,目錄結構如下: 生成後放在站點根目錄下的Plugins文件夾中, ...
  • 今天分享一個 WPF 版的ColorDialog,該控制項源自 這裡,不過筆者已經該控制項做了大量的修改工作,以適應自己的產品需求,閑話少說,先看看效果圖: 1、DropDownCustomColorPicker 效果圖 先看原項目的(喜歡這種方式的,請到 這裡 下載源碼 ) 被筆者修改之後的效果圖: ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...