C# List 定義及七種常用方法

1note-2527458

看完了以家人之名後,大叔該專心回來分享c#教學了,大叔的工作寫C#程式也有四年多了,以前寫PHP時那種結合陣列(associative array)寫的很爽,現在用C#來工作,那種向量陣列(vector array)(C、C++、Java、C#…),事先就得宣告陣列大小,讓我有點不適應,你想想如果我要做一個以家人之名的演員陣列,那是不是我要先看完所有40集的電視後才能確定陣列的大小。

而在PHP中,我可以這樣寫,看到哪寫到哪:

$actors = array();
$actors['李尖尖'] = '譚松韻';
$actors['凌霄'] = '宋威龍';
$actors['賀子秋'] = '張新成';
print_r($actors);

在C# 裡其實也有類似PHP的結合陣列用法,就是使用List內建泛型類別,這有點像是不用宣告長度的陣列(Array),是沒有PHP那樣的直覺,需要稍微記一下 list這個單字,怕忘記可以將這篇c# 教學文章加到我的最愛或是書籤中喔,以後有需要再點進來看。

什麼是 C# List?

命名空間:System.Collections.Generic

組件:mscorlib.dll, System.Collections.dll

表示可以依照索引存取的強類型物件列表。 提供搜尋、排序和管理清單的方法。

宣告:

//範例1:
List<T> mList = new List<T>();        //T爲列表中元素類型,現在以string類型作爲例子:
List<string> mList = new List<string>();

//範例2:
List<T> testList =new List<T> (IEnumerable<T> collection);  //以一個集合作爲參數創建List:
string[] temArr = { "李尖尖", "凌霄", "賀子秋", "李海潮", "凌和平", "齊明月", "唐燦", "杜鵑"};
List<string> testList = new List<string>(temArr);

List<T>裡的’T’是什麼?

List<T>是.NET Framework類別庫提供的泛型集合,將<>號裡面的T改成我們指定的型別,就會產生對應型別的集合,存入取出的過程都會是我們指定的型別,而不用每次都轉換成object影響到效能,編譯器也會知道我們指定成什麼型別,幫我們正確的進行型別檢查,免得執行時才發現選錯型別。

常用的屬性和方法

屬性

說明

Capacity

在不需要調整大小之下,取得或設定內部資料結構可以保存的項目總數。

Count

取得 List中包含的元素數目

Item

取得或設定索引中的項目

 

方法 說明
Add 將物件加入至 List的最後面
AddRange 將特定集合的元素加入至 List的最後面
BinarySearch 使用預設的比較子並傳回元素以零為起始的索引,來搜尋元素之整個排序的 List
 

Clear

將所有元素從 List中移除
Contains 判斷元素是否在 List中
Equals(Object) 判斷指定的物件是否等於目前的物件。
Find 擷取符合指定的元素,並傳回整個List中第一個相符的元素
Foreach 在 List 的每一個元素上執行指定之動作。
IndexOf(T) 搜尋指定的物件,並傳回整個 List 中第一個相符合元素的索引
Insert(Int32, T) 將元素插入至 List 中指定的索引位置
InsertRange(Int32, IEnumerable<T>) 將集合的元素插入位於指定索引的 List 中
Remove(T) 從 List 移除特定物件的第一個相符合元素
RemoveAt(Int32) 移除 List中指定索引的元素
RemoveRange(Int32, Int32) 從 List 移除的元素範圍。
Sort 使用預設比較子來排序整個 List 中的元素
TrimExcess 將容量設為 List 中元素的實際數目,如果該數目小於臨界值。
TrueForAll 判斷 List 中的每一個元素是否符合指定之述詞所定義的條件。

C# List的Add與AddRange方法

(1)Add:添加單個元素

List<string>  Soundtracks1= new List<string>();
Soundtracks1.Add("無畏");
Soundtracks1.Add("我會守在這裡");
Soundtracks1.Add("看不見的光");
Soundtracks1.Add("Like A Breeze");
Soundtracks1.Add("雨");

再看一個c# list add new範例

using System;
using System.Collections.Generic;
// Simple business object. A PartId is used to identify the type of part
// but the part name can change.
public class Part : IEquatable<Part>
    {
        public string PartName { get; set; }

        public int PartId { get; set; }

        public override string ToString()
        {
            return "ID: " + PartId + "   Name: " + PartName;
        }
        public override bool Equals(object obj)
        {
            if (obj == null) return false;
            Part objAsPart = obj as Part;
            if (objAsPart == null) return false;
            else return Equals(objAsPart);
        }
        public override int GetHashCode()
        {
            return PartId;
        }
        public bool Equals(Part other)
        {
            if (other == null) return false;
            return (this.PartId.Equals(other.PartId));
        }
    // Should also override == and != operators.
    }
public class Example
{
    public static void Main()
    {
        // Create a list of parts.
        List<Part> parts = new List<Part>();

        // Add parts to the list.
        parts.Add(new Part() { PartName = "crank arm", PartId = 1234 });
        parts.Add(new Part() { PartName = "chain ring", PartId = 1334 });
        parts.Add(new Part() { PartName = "regular seat", PartId = 1434 });
        parts.Add(new Part() { PartName = "banana seat", PartId = 1444 });
        parts.Add(new Part() { PartName = "cassette", PartId = 1534 });
        parts.Add(new Part() { PartName = "shift lever", PartId = 1634 });

        // Write out the parts in the list. This will call the overridden ToString method
        // in the Part class.
        Console.WriteLine();
        foreach (Part aPart in parts)
        {
            Console.WriteLine(aPart);
        }

        // Check the list for part #1734. This calls the IEquatable.Equals method
        // of the Part class, which checks the PartId for equality.
        Console.WriteLine("nContains("1734"): {0}",
        parts.Contains(new Part { PartId = 1734, PartName = "" }));

        // Insert a new item at position 2.
        Console.WriteLine("nInsert(2, "1834")");
        parts.Insert(2, new Part() { PartName = "brake lever", PartId = 1834 });

        //Console.WriteLine();
        foreach (Part aPart in parts)
        {
            Console.WriteLine(aPart);
        }

        Console.WriteLine("nParts[3]: {0}", parts[3]);

        Console.WriteLine("nRemove("1534")");

        // This will remove part 1534 even though the PartName is different,
        // because the Equals method only checks PartId for equality.
        parts.Remove(new Part() { PartId = 1534, PartName = "cogs" });

        Console.WriteLine();
        foreach (Part aPart in parts)
        {
            Console.WriteLine(aPart);
        }
        Console.WriteLine("nRemoveAt(3)");
        // This will remove the part at index 3.
        parts.RemoveAt(3);

        Console.WriteLine();
        foreach (Part aPart in parts)
        {
            Console.WriteLine(aPart);
        }

            /*

             ID: 1234   Name: crank arm
             ID: 1334   Name: chain ring
             ID: 1434   Name: regular seat
             ID: 1444   Name: banana seat
             ID: 1534   Name: cassette
             ID: 1634   Name: shift lever

             Contains("1734"): False

             Insert(2, "1834")
             ID: 1234   Name: crank arm
             ID: 1334   Name: chain ring
             ID: 1834   Name: brake lever
             ID: 1434   Name: regular seat
             ID: 1444   Name: banana seat
             ID: 1534   Name: cassette
             ID: 1634   Name: shift lever

             Parts[3]: ID: 1434   Name: regular seat

             Remove("1534")

             ID: 1234   Name: crank arm
             ID: 1334   Name: chain ring
             ID: 1834   Name: brake lever
             ID: 1434   Name: regular seat
             ID: 1444   Name: banana seat
             ID: 1634   Name: shift lever

             RemoveAt(3)

             ID: 1234   Name: crank arm
             ID: 1334   Name: chain ring
             ID: 1834   Name: brake lever
             ID: 1444   Name: banana seat
             ID: 1634   Name: shift lever


         */
    }
}

 

(2)AddRange:添加實作了界面IEnumerable<T>的一個泛型集合的所有元素到指定泛型集合末尾

string[] input = { "無畏", "我會守在這裡", "看不見的光" };
List<string> Soundtracks2 = new List<string>(input);
Soundtracks2.AddRange(dinosaurs);

※2022/07/28

今天分享一個c# list add list的範例,中文白話的意思就是使用 C# 中的 List.AddRange() 函式將列表新增到另一個列表

以下程式碼範例展示如何使用 C# 中的 List.AddRange() 函式將一個列表新增到另一個列表。

using System;
using System.Collections.Generic;

namespace add_list
{
        static void Main(string[] args)
        {
            List<string> first = new List<string> { "do", "rey", "me" };
            List<string> second = new List<string> { "fa", "so", "la", "te" };
            first.AddRange(second);
            foreach(var e in first)
            {
                Console.WriteLine(e);

            }
        }
    }
}

輸出:

do
rey
me
fa
so
la
te

 

用foreach 取出List 裡的值

// 可用foreach 取出List 裡的值
foreach(string myStringList in Soundtracks1)
{
        Console.WriteLine(myStringList);
}

程式輸出如圖:

// 取出單一個List 裡的值,如同陣列(Array)用法
// 無畏
Soundtracks2[0];

// 無畏
Soundtracks1[0];

下面的程式碼可以顯示List中第三個元素值
Console.WriteLine(Soundtracks1[2]);

如何使用 C# List 屬性

List 的 Capacity 代表集合的容量,Count 代表集合中的數量

隨著項目新增至 List 物件中,會重新配置內部陣列來增加容量。

重新配置的意義:

當加入新項目至 List 物件中時會去檢查 List 物件的 Capacity 與 Count 屬性值

當 Count 等於 Capacity,會自動重新配置內部陣列,並將新陣列的容量設為 Capacity 的倍數,並且在加入新項目以前,複製現有項目至新陣列,接著再將新項目加入。

成本:

      1.建立一個新的內部陣列

      2.將現有項目複製到新的內部陣列中

 當 List 物件中的項目多且項目資料量大時,重新配置的成本不小。

using System;
using System.Collections.Generic;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            List<string> Soundtracks1 = new List<string>();
            Soundtracks1.Add("無畏");
            Soundtracks1.Add("我會守在這裡");
            Soundtracks1.Add("看不見的光");
            Soundtracks1.Add("Like A Breeze");
            Soundtracks1.Add("雨");

            output(Soundtracks1);

            Soundtracks1.Add("If Rain");

            output(Soundtracks1);

            Soundtracks1.AddRange(new string[] {"My Everything","金鼎巷","杏林湾商务运营中心","莲花新城公交站947路" });

            output(Soundtracks1);

            Soundtracks1.AddRange(new string[] { "李尖尖", "凌霄", "賀子秋", "李海潮" });

            output(Soundtracks1);

            Console.ReadLine();

            //List count = 5, capacity = 8
            //List count = 6, capacity = 8
            //List count = 10, capacity = 16
            //List count = 14, capacity = 16
        }

        static void output(List<string> l)
        {
            Console.WriteLine("List count={0}, capacity={1}", l.Count, l.Capacity);
        }
    }
}

所以一般建議若項目數量是可預測的話,在建立 List<T> 物件時就設定 Capacity 大小,看到capacity的配置後,想要寫爽變動陣列,還是要考慮一下程式效能。

List<string>  testList  = new List<string>(32)

當 List<T> 物件項目加入完成後可使用 TrimExcess() 方法,或設定 Capacity  = Count 來減少不必要的記憶體空間,不過這些舉動也會引發重新配置。

但使用TrimExcess() 方法時會去檢查項目大於容量的 90%,就不會執行重新配置,避免為取得一點利益而產生昂貴的重新配置成本。

myList.TrimExcess();  //視情況重新配置

myList.Capacity = myList.Count;

C#中使用List集合的Insert方法在指定位置插入元素

在C#的List集合等資料型別變數中,我們可以使用c# list insert方法在指定的索引位置插入一個新元素,例如指定在List集合的第一個位置寫入一個新元素或者在List集合的中間某個位置插入一個新元素。List集合類的Insert方法的格式為ListObj.Insert(index,listNewObject),其中ListObj代表List集合物件,index代表要插入元素的位置,listNewObject表示插入值。

例如我們有個string型別的List集合actorsList,我們需要在actorsList集合的第一個位置插入”谭松韵”,則可以使用下列語法來實現:

actorsList.Insert(0,”谭松韵”);

InsertRange(int index,IEnumerable<T> items) 在index下標處插入一組元素,該下標以及之後的元素依次後移

下面的程式碼在第3個位置插入一個字串,在第2個位置插入一個集合

testList.Insert(3, "塗松岩"); 
// Collection of new authors 
string[] newAuthors = { "張晞臨", "孫銥", "何瑞賢" }; 
// Insert array at position 2 
testList.InsertRange(2, newAuthors);

C# 從集合中刪除元素

1.C# 使用 Remove() 方法從 List 中刪除元素

這個 Remove() 方法根據集合上的名稱刪除元素。此方法的語法如下:

ListName.Remove(“NameOfItemInList”);

範例:

using System;
using System.Collections.Generic;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            List<string> Soundtracks1 = new List<string>();
            Soundtracks1.Add("無畏");
            Soundtracks1.Add("我會守在這裡");
            Soundtracks1.Add("看不見的光");
            Soundtracks1.Add("Like A Breeze");
            Soundtracks1.Add("雨");           

            output(Soundtracks1);

            Soundtracks1.Add("If Rain");

            output(Soundtracks1);

            Soundtracks1.AddRange(new string[] {"My Everything","金鼎巷","杏林湾商务运营中心","莲花新城公交站947路" });

            output(Soundtracks1);

            Soundtracks1.AddRange(new string[] { "李尖尖", "凌霄", "賀子秋", "李海潮" });

            output(Soundtracks1);

            string[] temArr = { "李尖尖", "凌霄", "賀子秋", "李海潮", "凌和平", "齊明月", "唐燦", "杜鵑" };
            List<string> testList = new List<string>(temArr);
            testList.Insert(3, "塗松岩");
            // Collection of new authors 
            string[] newAuthors = { "張晞臨", "孫銥", "何瑞賢" };
            // Insert array at position 2 
            testList.InsertRange(2, newAuthors);

            Console.WriteLine("刪除前集合:");
            foreach (string myStringList in testList)
            {
                Console.WriteLine(myStringList);
            }

            Console.WriteLine();

            //Use of Remove() method
            testList.Remove("孫銥");
            Console.WriteLine("刪除後集合:");
            foreach (string myStringList in testList)
            {
                Console.WriteLine(myStringList);
            }

            Console.ReadLine();

            //List count = 5, capacity = 8
            //List count = 6, capacity = 8
            //List count = 10, capacity = 16
            //List count = 14, capacity = 16
        }

        static void output(List<string> l)
        {
            Console.WriteLine("List count={0}, capacity={1}", l.Count, l.Capacity);
        }
    }
}

2.C# 使用 RemoveAt() 方法從 List 中刪除元素

RemoveAt() 方法根據該元素的索引位置從 List 中刪除該元素。要知道 C# 中的索引以 0 開頭。因此,選擇索引位置時要小心。此方法的語法如下:

ListName.RemoveAt(Index);

範例:

using System;
using System.Collections.Generic;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            List<string> Soundtracks1 = new List<string>();
            Soundtracks1.Add("無畏");
            Soundtracks1.Add("我會守在這裡");
            Soundtracks1.Add("看不見的光");
            Soundtracks1.Add("Like A Breeze");
            Soundtracks1.Add("雨");    
            output(Soundtracks1);

            Soundtracks1.Add("If Rain");
            output(Soundtracks1);

            Soundtracks1.AddRange(new string[] {"My Everything","金鼎巷","杏林湾商务运营中心","莲花新城公交站947路" });
            output(Soundtracks1);

            Soundtracks1.AddRange(new string[] { "李尖尖", "凌霄", "賀子秋", "李海潮" });
            output(Soundtracks1);

            string[] temArr = { "李尖尖", "凌霄", "賀子秋", "李海潮", "凌和平", "齊明月", "唐燦", "杜鵑" };
            List<string> testList = new List<string>(temArr);
            testList.Insert(3, "塗松岩");
            // Collection of new authors 
            string[] newAuthors = { "張晞臨", "孫銥", "何瑞賢" };
            // Insert array at position 2 
            testList.InsertRange(2, newAuthors);
            Console.WriteLine("刪除前集合:");
            foreach (string myStringList in testList)
            {
                Console.WriteLine(myStringList);
            }
            Console.WriteLine();
            //Use of RemoveAt() method
            testList.RemoveAt(3);
            Console.WriteLine("刪除後集合:");
            foreach (string myStringList in testList)
            {
                Console.WriteLine(myStringList);
            }
            Console.ReadLine();

            //List count = 5, capacity = 8
            //List count = 6, capacity = 8
            //List count = 10, capacity = 16
            //List count = 14, capacity = 16
        }
        static void output(List<string> l)
        {
            Console.WriteLine("List count={0}, capacity={1}", l.Count, l.Capacity);
        }
    }
}

3.C# 使用 RemoveRange() 方法從 List 中刪除元素

在 C# 中,我們也可以同時刪除多個元素。為此,可以使用 RemoveRange() 方法。將要刪除的元素範圍作為引數傳遞給該方法。此方法的語法如下:

ListName.RemoveRange(int index, int count);

index 是要刪除的元素的起始索引,count 是要刪除的元素的數量。

範例:

using System;
using System.Collections.Generic;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            List<string> Soundtracks1 = new List<string>();
            Soundtracks1.Add("無畏");
            Soundtracks1.Add("我會守在這裡");
            Soundtracks1.Add("看不見的光");
            Soundtracks1.Add("Like A Breeze");
            Soundtracks1.Add("雨");
            output(Soundtracks1);

            Soundtracks1.Add("If Rain");
            output(Soundtracks1);

            Soundtracks1.AddRange(new string[] {"My Everything","金鼎巷","杏林湾商务运营中心","莲花新城公交站947路" });
            output(Soundtracks1);

            Soundtracks1.AddRange(new string[] { "李尖尖", "凌霄", "賀子秋", "李海潮" });
            output(Soundtracks1);

            string[] temArr = { "李尖尖", "凌霄", "賀子秋", "李海潮", "凌和平", "齊明月", "唐燦", "杜鵑" };
            List<string> testList = new List<string>(temArr);
            testList.Insert(3, "塗松岩");
            // Collection of new authors 
            string[] newAuthors = { "張晞臨", "孫銥", "何瑞賢" };
            // Insert array at position 2 
            testList.InsertRange(2, newAuthors);

            Console.WriteLine("刪除前集合:");
            foreach (string myStringList in testList)
            {
                Console.WriteLine(myStringList);
            }
            Console.WriteLine();

            //Use of RemoveRange() method
            testList.RemoveRange(3, 2);
            Console.WriteLine("刪除後集合:");
            foreach (string myStringList in testList)
            {
                Console.WriteLine(myStringList);
            }
            Console.ReadLine();

            //List count = 5, capacity = 8
            //List count = 6, capacity = 8
            //List count = 10, capacity = 16
            //List count = 14, capacity = 16
        }
        static void output(List<string> l)
        {
            Console.WriteLine("List count={0}, capacity={1}", l.Count, l.Capacity);
        }
    }
}

4.C#中List集合使用Clear方法清空集合

在C#中的List集合操作過程中,有時候需要清空List集合中的元素,將之重置為一個初始化的List集合,此時就可以使用到List集合的擴展方法Clear()方法,此方法將清空List集合中所有的元素,清空後List集合中的元素個數為0。

例如有個List<string>的集合list1,內部存儲7個字串,清空list1中的元素可使用下列語句:

List<string> list1 = new List<string>() { “李尖尖總是「善待這世界的尖銳」”, “譚松韻:「我很幸運,用童年治癒著自己的一生」”, “「李尖尖的人生哲學」”, “凌霄的成長,是選擇原諒”, “凌霄:「如果覺得做錯了,只有活著才能夠彌補」”, “賀子秋與童年和解,獲得媽媽的疼愛”, “家是永遠的避風港” };

list1.Clear();

C# List如何尋找元素?

有兩種方法:

1.使用IndexOf判斷元素第一次出現的索引位置

在C#的List集合操作中,有時候需要判斷元素在List集合中第一次出現的索引位置資訊,此時需要使用到List集合的IndexOf方法來判斷,如果元素存在List集合中,則IndexOf方法傳回所在的索引位置資訊,如果不存在則返回-1,IndexOf方法為int IndexOf(T item),item代表需要判斷的元素。

例如有個List<int>的集合list2,需要判斷數字17在list1集合中第一次出現的索引位置資訊:

List<int> list2 = new List<int>() { 5, 7, 3, 10,17, 15, 18, 20, 13, 2,12 };

var index=  list2.IndexOf(17);

計算結果為,index=4。

2.使用contains()方法,判斷元素是否包含特定值

語法:public bool Contains (T item);

範例:list2.Contains(17);

IndexOf 跟 contains在效能上的比較有滿多討論的,一般都說是IndexOf較好,測試範例如下:

            System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
            Random r = new Random();
            int value =r.Next(0, 100000000); //自己去變
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine("==========");
                Console.WriteLine("value=" + value);
                       stopwatch.Start();
                       bool IsContainValue = (list.IndexOf(value) != -1);
                       stopwatch.Stop();
                       Console.WriteLine(stopwatch.Elapsed);
                      stopwatch.Reset();         

                      stopwatch.Start();
                      list.Contains(value);
                      stopwatch.Stop();
                      Console.WriteLine(stopwatch.Elapsed);              

                      stopwatch.Reset();
                      //Console.WriteLine("==========");
                      value = r.Next(0, 100000000); //自己去變
            }

但ITREAD上有篇《List集合的contains() ,indexOf的比較》卻提到是『contains()效率比較高』,卻沒有範例佐證,是有點詭異的說法。

C# List 如何排序?

List<T>作為集合,排序也是它的一個基本功能。List<T>可以通過Sort()對集合中的元素進行從小到大排序,同時Sort()還接收自定義比較器,這樣開發人員可以根據需要指定希望的比較方式。Sort()方法的4個版本的定義如下:

  1. Sort() 使用預設的比較子來排序在整個 List<T> 中的元素。
  2. Sort(IComparer<T>) 使用指定的比較子來排序在整個 List<T> 中的元素
  3. Sort(Int32, Int32, IComparer<T>) 使用指定的比較子對 List<T> 中某段範圍內的元素進行排序。
  4. Sort(Comparison<T>) 使用指定的 Comparison<T> 來排序在整個 List<T> 中的元素。

方法一、Sort()

該方法為系統預設的方法,單一參數時會預設進行升序排序。

            List<int> list1 = new List<int>();
            int[] animals = { 989, 515, 298,112,581 };
            list1.AddRange(animals);
            list1.Sort();
            foreach (int myintList in list1)
            {
                Console.WriteLine(myintList);
            }

List<string> list2 = new List<string>();
            list2.Add("譚松韻");
            list2.Add("宋威龍");
            list2.Add("張新成");
            list2.Add("塗松岩");
            list2.Add("張晞臨");
            list2.Sort();
            foreach (string myintList in list2)
            {
                Console.WriteLine(myintList);
            }

如果遇到多參數(Name、Age)排序時,需要對該預設方法進行修改。

如果沒有修改這個方法,會產生未處理的例外狀況

System.InvalidOperationException: ‘無法比較陣列中的兩個元素。’

ArgumentException: 至少一個物件必須實作 IComparable。

A:People類別繼承IComparable介面,實作CompareTo()方法

IComparable<T>:定義由值型別或類別實作的通用比較方法,為了在建立特定於型別的比較方法以對元素進行排序。

原理:自行實作的CompareTo()方法會在list.Sort()內部進行元素兩兩比較,最後實作排序

 

public class People : IComparable<People>
    {
        public int Age { get; set; }
        public string Name { get; set; }
        public People(string name, int age)
        {
            this.Name = name;
            this.Age = age;
        }
        public override string ToString()
        {
            string result = "";
            result = "[" + this.Name + "," + this.Age.ToString() + "]";
            return result;
        }
        // list.Sort()時會根據該CompareTo()進行自定義比較
        public int CompareTo(People other)
        {
            int x = this.Name.CompareTo(other.Name);
            if (x == 0)
            {
                if (this.Age > other.Age)
                    x = 1;
                else if (this.Age == other.Age)
                    x = 0;
                else
                    x = -1;
            }
            return x;
        }
    }

List<People> peopleList = new List<People>();
            peopleList.Add(new People("譚松韻", 31));
            peopleList.Add(new People("譚松韻", 22));
            peopleList.Add(new People("宋威龍", 22));
            peopleList.Add(new People("張新成", 26));
            peopleList.Add(new People("塗松岩", 45));
            peopleList.Add(new People("張晞臨", 55));
            peopleList.Add(new People("張晞臨", 65));
            peopleList.Sort();

            foreach (People myintList in peopleList)
            {
                Console.WriteLine(myintList.Name+","+ myintList.Age);
            }
            Console.ReadLine();

方法二、Sort(IComparer<T>)  

使用指定的比較子來排序在整個 List<T> 中的元素

跟上述繼承IComparable的方法不同,這個方法不可在People內繼承實作IComparer介面,而是需要新建比較方法類別進行介面實作

B.新建PeopleComparer類別、繼承IComparer介面、實作Compare()方法

原理:list.Sort()將PeopleComparer類別的元素作為引數,在內部使用Compare()方法進行兩兩比較,最終實作排序(注意:上述方法為CompareTo(),此處為Compare()方法)

    // 自定義比較方法類別
    class PeopleComparer : IComparer<People>
    {
        // 不同於CompareTo()單引數,此處為雙引數
        public int Compare(People x, People y)
        {
            if (x.Name != y.Name)
            {
                return x.Name.CompareTo(y.Name);
            }
            else if (x.Age != y.Age)
            {
                return x.Age.CompareTo(y.Age);
            }
            else return 0;
        }
    }

            // 客戶端
            // 傳入引數為自定義比較類別的元素  
            peopleList.Sort(new PeopleComparer());
            foreach (People myintList in peopleList)
            {
                Console.WriteLine(myintList.Name + "," + myintList.Age);
            }
            Console.ReadLine();

方法三、Sort(Int32, Int32, IComparer<T>)

使用指定的比較子對 List<T> 中某段範圍內的元素進行排序。

原理:List<T>.Sort(int index,, int count, IComparer<T> Comparer) 方法的引數:待排元素起始索引、待排元素個數、排序方法

            // 客戶端
            // 傳入引數為自定義比較類別的元素  
            peopleList.Sort(2,3,new PeopleComparer());
            foreach (People myintList in peopleList)
            {
                Console.WriteLine(myintList.Name + "," + myintList.Age);
            }
            Console.ReadLine();

方法四、Sort(Comparison<T>)

使用指定的 Comparison<T> 來排序在整個 List<T> 中的元素。

不同於上述繼承介面的方法,此方法的引數為 泛型委派 Comparison<T>

委派原型:public delegate int Comparison<in T>(T x,T y);

C:依照委派的使用方法,首先建立委派執行個體MyComparison,並繫結到自定義的比較方法PeopleComparison()上,最終呼叫list.Sort()時 將委派執行個體傳入

原理:list.Sort()根據傳入的委派方法,進行兩兩元素比較最後實作排序

        public static int PeopleComparison(People p1, People p2)
        {
            if (p1.Name != p2.Name)
            {
                return p1.Name.CompareTo(p2.Name);
            }
            else if (p1.Age != p2.Age)
            {
                return p1.Age.CompareTo(p2.Age);
            }
            else return 0;
        }

        static void Main(string[] args)
        {
            List<People> peopleList = new List<People>();
            peopleList.Add(new People("譚松韻", 31));
            peopleList.Add(new People("譚松韻", 22));
            peopleList.Add(new People("宋威龍", 22));
            peopleList.Add(new People("張新成", 26));
            peopleList.Add(new People("塗松岩", 45));
            peopleList.Add(new People("張晞臨", 55));
            peopleList.Add(new People("張晞臨", 65));
            //peopleList.Sort();
            // 客戶端
            // 傳入引數為自定義比較類別的執行個體  
            //peopleList.Sort(2,3,new PeopleComparer());
            //foreach (People myintList in peopleList)
            //{
            //    Console.WriteLine(myintList.Name + "," + myintList.Age);
            //}
            //Console.ReadLine();

            // 方法0 建立委派執行個體並繫結
            Comparison<People> MyComparison = PeopleComparison;
            // 傳入該執行個體實作比較方法
            peopleList.Sort(MyComparison);
            foreach (People myintList in peopleList)
            {
                Console.WriteLine(myintList.Name + "," + myintList.Age);
            }
            Console.ReadLine();
        }

此外,既然Comparison<T>是泛型委派,則完全可以用 Lambda表示式進行描述

           // Lambda表示式實現Comparison委託
            peopleList.Sort((p1, p2) =>
            {
                if (p1.Age != p2.Age)
                {
                    return p2.Age.CompareTo(p1.Age);
                }               
                else if (p1.Name != p2.Name)
                {
                    return p2.Name.CompareTo(p1.Name);
                }
                else return 0;
            });

            foreach (People myintList in peopleList)
            {
                Console.WriteLine(myintList.Name + "," + myintList.Age);
            }
            Console.ReadLine();

如何反轉C# List的元素?

在C#的List集合操作中,有時候需要對List集合中的元素的順序進行倒序反轉操作,此時就可使用到List集合中的Reverse方法來實現此功能,Reverse方法的簽名爲void Reverse(),此方法不需要任何參數,呼叫void Reverse()方法可將整個List集合中的元素的順序反轉過來。

A.Reverse()

反轉整個 List<T> 中項目的順序。

例如有個List集合list1中含有元素1至10,需要將這個list1集合中的元素反轉爲10至1的倒序順序排列可使用下列語句:

   List<int> list1 = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

   list1.Reverse();

B.Reverse(Int32, Int32)

反向指定範圍中項目的順序。

public void Reverse (int index, int count);

參數

index Int32 要反向範圍內之以零為起始的起始索引。

count Int32 要反向範圍中的項目數。

例外狀況

ArgumentOutOfRangeException

index 小於 0。

-或- count 小於 0。

ArgumentException

index 和 count 不代表 List<T> 中項目的有效範圍。

如何搜尋 C# List 的元素?

List<T>的BinarySearch方法搜尋一個排序 List中的元素並傳回以零為起始的索引項目

多載

A.BinarySearch(T):使用預設的比較子並傳回項目以零為起始的索引,來搜尋項目之整個排序的 List<T>。

B.BinarySearch(T, IComparer<T>):使用指定的比較子並傳回項目以零為起始的索引,來搜尋項目之整個排序的 List<T>。

C.BinarySearch(Int32, Int32, T, IComparer<T>):使用指定的比較子在已經過排序之 List<T> 內,搜尋某範圍的項目,並傳回該項目以零為起始的索引。

A.BinarySearch(T)方法

用法:public int BinarySearch (T item);

參數:item T 要尋找的物件。 參考類型的值可以是 null。

傳回:Int32

如果有找到 item,則為已排序的 List<T> 中 item 之以零為起始的索引,否則便為負數,此負數為大於 item 的下一個項目索引之位元補數,或者,如果沒有更大的項目,則為 Count 的位元補數。

例外狀況:InvalidOperationException

預設比較子 Default 找不到 IComparable<T> 泛型介面的實作或 T 類型的 IComparable 介面。

範例:

List<string> Geek = new List<string>();
            Geek.Add("Coronavirus");
            Geek.Add("Election results");
            Geek.Add("Kobe Bryant");
            Geek.Add("Zoom");
            Geek.Add("IPL");

            Console.WriteLine("原來的List:");
            foreach (string g in Geek)
            {
                // prints original List
                Console.WriteLine(g);
            }
            Console.WriteLine("n排序後的List:");
            // sort the List
            Geek.Sort();
            Console.WriteLine();
            foreach (string g in Geek)
            {
                // prints the sorted List
                Console.WriteLine(g);
            }
            Console.WriteLine("n插入 India vs New Zealand:");

            // insert "India vs New Zealand" in the List
            //"India vs New Zealand" insert into its original 
            // position when the List is sorted
            int index = Geek.BinarySearch("India vs New Zealand");

            if (index < 0)
            {
                Geek.Insert(~index, "India vs New Zealand");
            }
            Console.WriteLine();

            foreach (string g in Geek)
            {
                // prints the sorted list
                // after inserting "EFGH"
                Console.WriteLine(g);
            }

輸出:

B.BinarySearch(T, IComparer<T>)方法

用法:public int BinarySearch (T item, System.Collections.Generic.IComparer<T>? comparer);

參數:

item T

要尋找的物件。 參考類型的值可以是 null。

comparer IComparer<T>

比較項目時所要使用的 IComparer<T> 實作。

-或- null 表示使用預設比較子 Default。

傳回:

Int32

如果有找到 item,則為已排序的 List<T> 中 item 之以零為起始的索引,否則便為負數,此負數為大於 item 的下一個項目索引之位元補數,或者,如果沒有更大的項目,則為 Count 的位元補數。

例外狀況:

InvalidOperationException

comparer 為 null,而且預設比較子 Default 找不到 IComparable<T> 泛型介面的實作或 T 類型的 IComparable 介面。

範例:

下列範例是來自微軟的,但因為翻譯怪怪的,所以我重新翻譯了一下,範例示範方法多載 Sort(IComparer<T>) 和方法多載 BinarySearch(T, IComparer<T>) 。

這個範例會針對名為 DinoCompare 的字串定義替代比較子實作 IComparer<string> (在Visual Basic是 IComparer(Of String),在 Visual C++是 IComparer<String^> ) 泛型介面,比較子的運作方式如下:首先,會測試比較 null 值的,而且會將 null 參考視為小於非 null。 其次,會比較字串長度,而較長的字串會被視為較大的。 第三,如果長度相等,則會使用一般字串比較。

字串的 List<T> 會被建立,並填入四個字串,四個字串沒有特定的順序。 list 隨即顯示,並使用替代比較子排序,然後再次顯示。

BinarySearch(T, IComparer<T>)然後會使用方法多載來搜尋不在 list 中的數個字串,採用替代比較子。 Insert方法是用來插入字串。 這兩個方法位於名為的函式中 SearchAndInsert ,以及使用BinarySearch(T, IComparer<T>)傳回的索引值做位元補數 (在 C # 和 Visual C++ 中是用 ~ 運算子,在Visual Basic中使用 Xor -1 運算子)取得負數,並使用它作為插入新字串的索引。

using System;
using System.Collections.Generic;

public class DinoComparer: IComparer<string>
{
    public int Compare(string x, string y)
    {
        if (x == null)
        {
            if (y == null)
            {
                // If x is null and y is null, they're
                // equal.
                return 0;
            }
            else
            {
                // If x is null and y is not null, y
                // is greater.
                return -1;
            }
        }
        else
        {
            // If x is not null...
            //
            if (y == null)
                // ...and y is null, x is greater.
            {
                return 1;
            }
            else
            {
                // ...and y is not null, compare the
                // lengths of the two strings.
                //
                int retval = x.Length.CompareTo(y.Length);

                if (retval != 0)
                {
                    // If the strings are not of equal length,
                    // the longer string is greater.
                    //
                    return retval;
                }
                else
                {
                    // If the strings are of equal length,
                    // sort them with ordinary string comparison.
                    //
                    return x.CompareTo(y);
                }
            }
        }
    }
}

public class Example
{
    public static void Main()
    {
        List<string> dinosaurs = new List<string>();
        dinosaurs.Add("Pachycephalosaurus");
        dinosaurs.Add("Amargasaurus");
        dinosaurs.Add("Mamenchisaurus");
        dinosaurs.Add("Deinonychus");
        Display(dinosaurs);

        DinoComparer dc = new DinoComparer();

        Console.WriteLine("nSort with alternate comparer:");
        dinosaurs.Sort(dc);
        Display(dinosaurs);

        SearchAndInsert(dinosaurs, "Coelophysis", dc);
        Display(dinosaurs);

        SearchAndInsert(dinosaurs, "Oviraptor", dc);
        Display(dinosaurs);

        SearchAndInsert(dinosaurs, "Tyrannosaur", dc);
        Display(dinosaurs);

        SearchAndInsert(dinosaurs, null, dc);
        Display(dinosaurs);
    }

    private static void SearchAndInsert(List<string> list,
        string insert, DinoComparer dc)
    {
        Console.WriteLine("nBinarySearch and Insert "{0}":", insert);

        int index = list.BinarySearch(insert, dc);

        if (index < 0)
        {
            list.Insert(~index, insert);
        }
    }

    private static void Display(List<string> list)
    {
        Console.WriteLine();
        foreach( string s in list )
        {
            Console.WriteLine(s);
        }
    }
}

/* This code example produces the following output:

Pachycephalosaurus
Amargasaurus
Mamenchisaurus
Deinonychus

Sort with alternate comparer:

Deinonychus
Amargasaurus
Mamenchisaurus
Pachycephalosaurus

BinarySearch and Insert "Coelophysis":

Coelophysis
Deinonychus
Amargasaurus
Mamenchisaurus
Pachycephalosaurus

BinarySearch and Insert "Oviraptor":

Oviraptor
Coelophysis
Deinonychus
Amargasaurus
Mamenchisaurus
Pachycephalosaurus

BinarySearch and Insert "Tyrannosaur":

Oviraptor
Coelophysis
Deinonychus
Tyrannosaur
Amargasaurus
Mamenchisaurus
Pachycephalosaurus

BinarySearch and Insert "":


Oviraptor
Coelophysis
Deinonychus
Tyrannosaur
Amargasaurus
Mamenchisaurus
Pachycephalosaurus
 */

C.BinarySearch(Int32, Int32, T, IComparer<T>)方法

用法:public int BinarySearch (int index, int count, T item, System.Collections.Generic.IComparer<T>? comparer);

參數:

index Int32 要搜尋範圍內之以零為起始的起始索引。

count Int32 搜尋範圍的長度。

item T 要尋找的物件。 參考類型的值可以是 null。

comparer IComparer<T> 比較項目時要使用的 IComparer<T> 實作,或 null 表示使用預設比較子 Default。

傳回:

Int32

如果有找到 item,則為已排序的 List<T> 中 item 之以零為起始的索引,否則便為負數,此負數為大於 item 的下一個項目索引之位元補數,或者,如果沒有更大的項目,則為 Count 的位元補數。例外狀況:

ArgumentOutOfRangeException index 小於 0。 -或- count 小於 0。

ArgumentException index 和 count 不代表 List<T> 中的有效範圍。

InvalidOperationException comparer 為 null,而且預設比較子 Default 找不到 IComparable<T> 泛型介面的實作或 T 類型的 IComparable 介面。

 

範例:

下列範例一樣取自微軟的範例,也是因為中文翻譯怪怪的,所以分享在這篇文章中,這個範例示範方法多載 Sort(Int32, Int32, IComparer<T>) 和方法多載 BinarySearch(Int32, Int32, T, IComparer<T>) 。

這個範例會針對名為 DinoCompare 的字串定義替代比較子,實作 IComparer<string>(Visual Basic 中以 IComparer(Of String),在 Visual C++ 則是以 IComparer<String^>  泛型介面中執行),比較子的運作方式如下:首先,會測試比較 null 值的,而且會將 null 參考視為小於非 null。 其次,會比較字串長度,而較長的字串會被視為較大的。 第三,如果長度相等,則會使用一般字串比較。

List<T>會建立字串的,並填入五個 herbivorous dinosaurs 和三個 carnivorous dinosaurs 的名稱。 在這兩個群組中,這些名稱不會有任何特定的排序次序。 隨即顯示 list、使用替代比較子排序 herbivores 的範圍,然後再次顯示 list。

BinarySearch(Int32, Int32, T, IComparer<T>)方法多載被用來搜尋 “Brachiosaurus” 的 herbivores 範圍。 找不到字串,且位補數 (在 C# 和 Visual C++ 中使用 ~ 運算子,而Visual Basic中使用 Xor -1方法)是負的, BinarySearch(Int32, Int32, T, IComparer<T>) 會用來做為插入新字串的索引。

 

using System;
using System.Collections.Generic;

public class DinoComparer: IComparer<string>
{
    public int Compare(string x, string y)
    {
        if (x == null)
        {
            if (y == null)
            {
                // If x is null and y is null, they're
                // equal.
                return 0;
            }
            else
            {
                // If x is null and y is not null, y
                // is greater.
                return -1;
            }
        }
        else
        {
            // If x is not null...
            //
            if (y == null)
                // ...and y is null, x is greater.
            {
                return 1;
            }
            else
            {
                // ...and y is not null, compare the
                // lengths of the two strings.
                //
                int retval = x.Length.CompareTo(y.Length);

                if (retval != 0)
                {
                    // If the strings are not of equal length,
                    // the longer string is greater.
                    //
                    return retval;
                }
                else
                {
                    // If the strings are of equal length,
                    // sort them with ordinary string comparison.
                    //
                    return x.CompareTo(y);
                }
            }
        }
    }
}

public class Example
{
    public static void Main()
    {
        List<string> dinosaurs = new List<string>();
        dinosaurs.Add("Pachycephalosaurus");
        dinosaurs.Add("Amargasaurus");
        dinosaurs.Add("Mamenchisaurus");
        dinosaurs.Add("Deinonychus");
        Display(dinosaurs);

        DinoComparer dc = new DinoComparer();

        Console.WriteLine("nSort with alternate comparer:");
        dinosaurs.Sort(dc);
        Display(dinosaurs);

        SearchAndInsert(dinosaurs, "Coelophysis", dc);
        Display(dinosaurs);

        SearchAndInsert(dinosaurs, "Oviraptor", dc);
        Display(dinosaurs);

        SearchAndInsert(dinosaurs, "Tyrannosaur", dc);
        Display(dinosaurs);

        SearchAndInsert(dinosaurs, null, dc);
        Display(dinosaurs);
    }

    private static void SearchAndInsert(List<string> list,
        string insert, DinoComparer dc)
    {
        Console.WriteLine("nBinarySearch and Insert "{0}":", insert);

        int index = list.BinarySearch(insert, dc);

        if (index < 0)
        {
            list.Insert(~index, insert);
        }
    }

    private static void Display(List<string> list)
    {
        Console.WriteLine();
        foreach( string s in list )
        {
            Console.WriteLine(s);
        }
    }
}

/* This code example produces the following output:

Pachycephalosaurus
Amargasaurus
Mamenchisaurus
Deinonychus

Sort with alternate comparer:

Deinonychus
Amargasaurus
Mamenchisaurus
Pachycephalosaurus

BinarySearch and Insert "Coelophysis":

Coelophysis
Deinonychus
Amargasaurus
Mamenchisaurus
Pachycephalosaurus

BinarySearch and Insert "Oviraptor":

Oviraptor
Coelophysis
Deinonychus
Amargasaurus
Mamenchisaurus
Pachycephalosaurus

BinarySearch and Insert "Tyrannosaur":

Oviraptor
Coelophysis
Deinonychus
Tyrannosaur
Amargasaurus
Mamenchisaurus
Pachycephalosaurus

BinarySearch and Insert "":


Oviraptor
Coelophysis
Deinonychus
Tyrannosaur
Amargasaurus
Mamenchisaurus
Pachycephalosaurus
 */

c# list find 尋找符合的條件

你一定感到有點納悶,有了IndexOf跟Contains方法就可以尋找相符的項目,如果複雜點也可以用sort方法搭配BinarySearch來搜尋,實在不太懂Find方法有什麼必要性,不過有人有使用IndexOf跟BinarySearch做比較,大概在項目數70~100之間就會有轉折的不同,100個以上項目時,用sort方法搭配BinarySearch來搜尋會比較快,70個項目數以下使用IndexOf較快,這個實驗可以參閱List<T>线性查找和二分查找BinarySearch效率分析,那Find跟IndexOf呢?一樣都是使用線性的方法,或許也可以做個實驗來看看。

List<T>.Find(Predicate<T>) 方法的定義是這樣的:
命名空間:
System.Collections.Generic
組件:
mscorlib.dll, netstandard.dll
搜尋符合指定之述詞所定義的條件之項目,並傳回整個 List<T> 內第一個相符的項目。

我們一樣使用微軟的範例:

using System;
using System.Collections.Generic;
// Simple business object. A PartId is used to identify a part
// but the part name can change.
public class Part : IEquatable<Part>
{
    public string PartName { get; set; }
    public int PartId { get; set; }

    public override string ToString()
    {
        return "ID: " + PartId + "   Name: " + PartName;
    }
    public override bool Equals(object obj)
    {
        if (obj == null) return false;
        Part objAsPart = obj as Part;
        if (objAsPart == null) return false;
        else return Equals(objAsPart);
    }
    public override int GetHashCode()
    {
        return PartId;
    }
    public bool Equals(Part other)
    {
        if (other == null) return false;
        return (this.PartId.Equals(other.PartId));
    }
    // Should also override == and != operators.
}
public class Example
{
    public static void Main()
    {
        // Create a list of parts.
        List<Part> parts = new List<Part>();

        // Add parts to the list.
        parts.Add(new Part() { PartName = "crank arm", PartId = 1234 });
        parts.Add(new Part() { PartName = "chain ring", PartId = 1334 });
        parts.Add(new Part() { PartName = "regular seat", PartId = 1434 });
        parts.Add(new Part() { PartName = "banana seat", PartId = 1444 });
        parts.Add(new Part() { PartName = "cassette", PartId = 1534 });
        parts.Add(new Part() { PartName = "shift lever", PartId = 1634 }); ;

        // Write out the parts in the list. This will call the overridden ToString method
        // in the Part class.
        Console.WriteLine();
        foreach (Part aPart in parts)
        {
            Console.WriteLine(aPart);
        }

        // Check the list for part #1734. This calls the IEquatable.Equals method
        // of the Part class, which checks the PartId for equality.
        Console.WriteLine("nContains: Part with Id=1734: {0}",
            parts.Contains(new Part { PartId = 1734, PartName = "" }));

        // Find items where name contains "seat".
        //符合條件的第一個object,找不到傳回 null
        Console.WriteLine("nFind: Part where name contains "seat": {0}",
            parts.Find(x => x.PartName.Contains("seat")));

        // Check if an item with Id 1444 exists.
        //是否存在=> 存在回傳true
        Console.WriteLine("nExists: Part with Id=1444: {0}",
            parts.Exists(x => x.PartId == 1444));

        /*This code example produces the following output:

        ID: 1234   Name: crank arm
        ID: 1334   Name: chain ring
        ID: 1434   Name: regular seat
        ID: 1444   Name: banana seat
        ID: 1534   Name: cassette
        ID: 1634   Name: shift lever

        Contains: Part with Id=1734: False

        Find: Part where name contains "seat": ID: 1434   Name: regular seat

        Exists: Part with Id=1444: True
         */
    }
}

另一個範例增加了FindIndex、FindAll、FindLast的使用

using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;

namespace Find
{
    class Program
    {
        private static string IDtoFind = "bk109";

        private static List<Book> Books = new List<Book>();
        public static void Main(string[] args)
        {
            FillList();

            // Find a book by its ID.
            Book result = Books.Find(
            delegate(Book bk)
            {
                return bk.ID == IDtoFind;
            }
            );
            if (result != null)
            {
                DisplayResult(result, "Find by ID: " + IDtoFind);
            }
            else
            {
                Console.WriteLine("nNot found: {0}", IDtoFind);
            }

            // Find last book in collection published before 2001.
            result = Books.FindLast(
            delegate(Book bk)
            {
                DateTime year2001 = new DateTime(2001,01,01);
                return bk.Publish_date < year2001;
            });
            if (result != null)
            {
                DisplayResult(result, "Last book in collection published before 2001:");
            }
            else
            {
                Console.WriteLine("nNot found: {0}", IDtoFind);
            }

            // Find all computer books.
            //符合條件的所有objects
            List<Book> results = Books.FindAll(FindComputer);
            if (results.Count != 0)
            {
                DisplayResults(results, "All computer:");
            }
            else
            {
                Console.WriteLine("nNo books found.");
            }

            // Find all books under $10.00.
            results = Books.FindAll(
            delegate(Book bk)
            {
                return bk.Price < 10.00;
            }
            );
            if (results.Count != 0)
            {
                DisplayResults(results, "Books under $10:");
            }
            else
            {
                Console.WriteLine("nNo books found.");
            }

            // Find index values.
            //符合條件的第一個index,找不到傳回 -1
            Console.WriteLine();
            int ndx = Books.FindIndex(FindComputer);
            Console.WriteLine("Index of first computer book: {0}", ndx);
            ndx = Books.FindLastIndex(FindComputer);
            Console.WriteLine("Index of last computer book: {0}", ndx);

            int mid = Books.Count / 2;
            ndx = Books.FindIndex(mid, mid, FindComputer);
            Console.WriteLine("Index of first computer book in the second half of the collection: {0}", ndx);

            ndx = Books.FindLastIndex(Books.Count - 1, mid, FindComputer);
            Console.WriteLine("Index of last computer book in the second half of the collection: {0}", ndx);
        }

        // Populates the list with sample data.
        private static void FillList()
        {

            // Create XML elements from a source file.
            XElement xTree = XElement.Load(@"c:tempbooks.xml");

            // Create an enumerable collection of the elements.
            IEnumerable<XElement> elements = xTree.Elements();

            // Evaluate each element and set set values in the book object.
            foreach (XElement el in elements)
            {
                Book book = new Book();
                book.ID = el.Attribute("id").Value;
                IEnumerable<XElement> props = el.Elements();
                foreach (XElement p in props)
                {

                    if (p.Name.ToString().ToLower() == "author")
                    {
                        book.Author = p.Value;
                    }
                    else if (p.Name.ToString().ToLower() == "title")
                    {
                        book.Title = p.Value;
                    }
                    else if (p.Name.ToString().ToLower() == "genre")
                    {
                        book.Genre = p.Value;
                    }
                    else if (p.Name.ToString().ToLower() == "price")
                    {
                        book.Price = Convert.ToDouble(p.Value);
                    }
                    else if (p.Name.ToString().ToLower() == "publish_date")
                    {
                        book.Publish_date = Convert.ToDateTime(p.Value);
                    }
                    else if (p.Name.ToString().ToLower() == "description")
                    {
                        book.Description = p.Value;
                    }
                }

                Books.Add(book);
            }

            DisplayResults(Books, "All books:");
        }

        // Explicit predicate delegate.
        private static bool FindComputer(Book bk)
        {

            if (bk.Genre == "Computer")
            {
                return true;
            }
        else
            {
                return false;
            }
        }

        private static void DisplayResult(Book result, string title)
        {
            Console.WriteLine();
            Console.WriteLine(title);
            Console.WriteLine("n{0}t{1}t{2}t{3}t{4}t{5}", result.ID,
                result.Author, result.Title, result.Genre, result.Price,
                result.Publish_date.ToShortDateString());
            Console.WriteLine();
        }

        private static void DisplayResults(List<Book> results, string title)
        {
            Console.WriteLine();
            Console.WriteLine(title);
            foreach (Book b in results)
            {

                Console.Write("n{0}t{1}t{2}t{3}t{4}t{5}", b.ID,
                    b.Author, b.Title, b.Genre, b.Price,
                    b.Publish_date.ToShortDateString());
            }
            Console.WriteLine();
        }
    }

    public class Book
    {
        public string ID { get; set; }
        public string Author { get; set; }
        public string Title { get; set; }
        public string Genre { get; set; }
        public double Price { get; set; }
        public DateTime Publish_date { get; set; }
        public string Description { get; set; }
    }
}

※2022/05/19

今天再補充一部list find c#的Youtube教學影片《C# List Searching and Finding》,我是有點聽不懂但可以看他的操作來學習

總結 

這篇c#教學文章說明如何使用 List<T> 類別來操作物件集合,還有分享如何新增、搜尋、排序及反轉排序 list 中的項目,這是最近大叔用C# 5年的心得,以上的分享或是翻譯有錯誤,也請各位告知或糾正,謝謝~~^^!

之前有人在問c# stringlist的用法,後來看到微軟的一個頁面上有提到StringList Class的使用,但這是在Microsoft.TeamFoundation.Build.WorkFlow.Activities命名空間中使用,是07/02/2014的文章,看起來也沒有更新了,所以微軟有這樣的提醒訊息:

We’re no longer updating this content regularly. Check the Microsoft Product Lifecycle for information about how this product, service, technology, or API is supported.

建議各位使用新的版本或是別的版本。

新手開發人員、剛接觸 C# 的開發人員,以及經驗豐富的 C# / .Net 開發人員想要學習 C# 程式設計的也可以上c#教學看。

學 C# 敢找機電整合工程師的工作嗎?

c#教學:

  1. .NET 技術講座:打造堅固耐用的 C# 程式碼
  2. 想用C#寫出可以把浮水印崁入相片

感謝你看到這裡,很快就可以離開了,但最好的獎勵行動就是按一下幫我分享或留言,感恩喔~

點我分享到Facebook

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *