Day 7 我們已經學過 Array:
int[] numbers = { 10, 20, 30 };
Array 可以:
保存多筆相同 Type 的資料
→ 使用 Index 取得元素
→ 使用 foreach 逐筆處理
但 Array 有一個重要特性:
建立之後,長度固定。
如果今天資料數量會持續增加或刪除呢?
例如:
購物車商品
訂單資料
使用者清單
交易紀錄
這時就可以使用:
List<T>
今天的重點:
使用
List<T>管理一組數量會變動的資料。
List<T> 是什麼?List<T> 是 C# 常用的一種 Collection。
Collection 可以先理解成:
用來保存與管理一組資料的容器。
例如:
List<int> numbers =
new List<int>();
代表:
numbers
→ 管理多個 int
如果是:
List<string> names =
new List<string>();
代表:
names
→ 管理多個 string
也可以保存自己建立的 Object:
List<Product> products =
new List<Product>();
代表:
products
→ 管理多個 Product Object
<T> 代表什麼?List<T> 裡面的:
T
代表 Type。
實際使用時,會換成真正要保存的 Type。
例如:
List<int>
→ int
List<string>
→ string
List<Product>
→ Product
所以:
List<T>
→ T 代表 List 裡元素的 Type
例如:
List<int> numbers =
new List<int>();
可以加入:
numbers.Add(10);
但不能:
numbers.Add("Amy"); // Error
因為:
List<int>
→ 元素 Type 是 int
這篇先理解到這裡即可。
Generic 的原理之後再介紹。
List<T> 有什麼不同?Day 7 已經學過 Array,所以這裡只比較重點。
int[] numbers =
new int[3];
代表:
長度 = 3
→ 建立後長度固定
List<int> numbers =
new List<int>();
numbers.Add(10);
numbers.Add(20);
numbers.Add(30);
numbers.Add(40);
List<T> 可以持續加入,也可以刪除資料。
| Array | List<T> |
|---|---|
| 長度固定 | 元素數量可以增加或刪除 |
.Length |
.Count |
| 可以使用 Index | 可以使用 Index |
可以使用 foreach |
可以使用 foreach |
可以先這樣理解:
Array
→ 適合長度明確、不需要改變的資料
List<T>
→ 適合資料數量可能增加或刪除的情況
List<T>?當資料:
有多筆
有先後順序
數量可能增加或刪除
可以考慮使用:
List<T>
例如:
List<Product>
→ 商品清單
List<Order>
→ 訂單清單
List<User>
→ 使用者清單
List<T>建立一個空的 List:
List<string> names =
new List<string>();
目前沒有任何元素:
Count
→ 0
也可以建立時直接放入資料:
List<string> names =
new List<string>
{
"Amy",
"Bob",
"Kevin"
};
內容:
[0] Amy
[1] Bob
[2] Kevin
Index 和 Array 一樣,從 0 開始。
Add():加入資料List<T> 很重要的一個能力,就是可以動態加入資料。
List<string> names =
new List<string>();
names.Add("Amy");
names.Add("Bob");
names.Add("Kevin");
現在:
[0] Amy
[1] Bob
[2] Kevin
如果再加入:
names.Add("Tom");
變成:
[0] Amy
[1] Bob
[2] Kevin
[3] Tom
所以:
Add()
→ 把新元素加入 List 最後面
Count:目前有幾筆資料?Array 使用:
array.Length
List 使用:
list.Count
例如:
Console.WriteLine(names.Count);
如果目前有 4 筆資料:
4
所以:
Array
→ Length
List<T>
→ Count
Count 是 List<T> 提供的 Property:
names.Count
不需要加 ()。
之後學 LINQ 時會看到:
Count()
那是 LINQ 提供的 Method,之後再介紹。
這和 Day 7 的 Array 一樣。
取得第一筆:
Console.WriteLine(names[0]);
結果:
Amy
也可以修改:
names[1] = "Tom";
所以:
[index]
→ 取得元素
→ 修改元素
如果:
Count = 3
有效 Index:
0
1
2
最後一個有效 Index 是:
Count - 1
超過範圍就會發生錯誤。
Remove():刪除指定資料假設:
List<string> names =
new List<string>
{
"Amy",
"Bob",
"Kevin"
};
執行:
names.Remove("Bob");
結果:
Amy
Kevin
所以:
Remove()
→ 根據資料內容刪除元素
如果有重複資料:
List<int> numbers =
new List<int>
{
10,
20,
10
};
numbers.Remove(10);
會移除第一個符合的 10。
結果:
20
10
RemoveAt():根據位置刪除如果知道要刪除哪個 Index,可以使用:
RemoveAt()
例如:
[0] Amy
[1] Bob
[2] Kevin
執行:
names.RemoveAt(1);
結果:
[0] Amy
[1] Kevin
刪除後,後面的 Index 會重新排列。
整理:
Remove()
→ 根據資料刪除
RemoveAt()
→ 根據 Index 刪除
Contains()判斷是否包含指定資料:
bool exists =
names.Contains("Amy");
Contains()
→ 是否包含指定元素
Clear()清空全部元素:
names.Clear();
執行後:
Console.WriteLine(names.Count);
結果:
0
Clear()
→ 清空所有元素
List 本身仍然存在,只是內容變成空的。
foreach 走訪 ListDay 7 已經學過 foreach。
List 也可以使用相同方式:
foreach (string name in names)
{
Console.WriteLine(name);
}
結果:
Amy
Bob
Kevin
所以:
foreach
→ 把 List 裡的元素
→ 一筆一筆取出來處理
把目前學過的操作放在一起:
// 建立
List<string> names =
new List<string>();
// 加入
names.Add("Amy");
names.Add("Bob");
// 查看數量
Console.WriteLine(names.Count);
// 取得
Console.WriteLine(names[0]);
// 刪除
names.Remove("Bob");
// 遍歷
foreach (string name in names)
{
Console.WriteLine(name);
}
這就是 List<T> 最基本的使用方式。
List<Product>:管理多個 Object前面的例子使用:
int
string
實務上更常遇到的是:
管理很多 Object。
例如商品資料。
先建立:
class Product
{
public string Name { get; private set; }
public decimal Price { get; private set; }
public Product(
string name,
decimal price)
{
Name = name;
Price = price;
}
}
一個 Product 代表一筆商品資料。
如果要管理很多商品:
List<Product> products =
new List<Product>();
products.Add(
new Product(
"Keyboard",
1500
)
);
products.Add(
new Product(
"Mouse",
800
)
);
products.Add(
new Product(
"Monitor",
6000
)
);
可以想成:
List<Product>
│
├── Product
│ ├── Name = Keyboard
│ └── Price = 1500
│
├── Product
│ ├── Name = Mouse
│ └── Price = 800
│
└── Product
├── Name = Monitor
└── Price = 6000
注意:
List 裡保存的是
Product Object,不是只有商品名稱。
Console.WriteLine(
$"商品數量:{products.Count}"
);
結果:
商品數量:3
Product firstProduct =
products[0];
products[0] 取得的是一個 Product Object。
所以可以繼續使用:
firstProduct.Name
firstProduct.Price
例如:
Console.WriteLine(
firstProduct.Name
);
結果:
Keyboard
foreach (Product product in products)
{
Console.WriteLine(
$"{product.Name} - ${product.Price}"
);
}
結果:
Keyboard - $1500
Mouse - $800
Monitor - $6000
整體:
很多 Product Object
↓
List<Product>
↓
集中管理
↓
foreach
↓
逐筆處理 Product
List<T> 也能搭配 PolymorphismDay 14 已經學過 Polymorphism。
例如:
List<Animal> animals =
new List<Animal>
{
new Dog(),
new Cat()
};
foreach (Animal animal in animals)
{
animal.MakeSound();
}
因為:
Dog is an Animal
Cat is an Animal
所以都可以放進:
List<Animal>
而:
MakeSound()
→ Dog 執行 Dog 的版本
→ Cat 執行 Cat 的版本
所以:
List<Animal>
→ 集中管理不同的 Animal Object
Polymorphism
→ 執行各自的行為
這裡知道可以這樣搭配即可。
建立:
class Student
{
public string Name { get; private set; }
public int Score { get; private set; }
public Student(
string name,
int score)
{
Name = name;
Score = score;
}
}
再建立:
List<Student> students =
new List<Student>();
加入:
Amy → 90
Bob → 75
Kevin → 85
完成:
1. 使用 Add() 加入三名 Student
2. 使用 Count 顯示學生數量
3. 使用 students[0]
取得第一名學生
4. 使用 foreach
顯示所有學生姓名與成績
5. 使用 RemoveAt()
刪除其中一名學生
6. 再次使用 foreach
查看刪除後結果
輸出例如:
學生數量:3
Amy - 90
Bob - 75
Kevin - 85
這篇先使用:
RemoveAt()
刪除自訂 Object。
自訂 Object 搭配 Remove()、Contains() 的判斷細節,之後再介紹。
今天最重要的是:
List<T>
→ 管理數量會變動的一組資料
常用操作:
Add()
→ 新增
Count
→ 數量
[index]
→ 取得 / 修改
Remove()
→ 根據資料刪除
RemoveAt()
→ 根據位置刪除
foreach
→ 逐筆處理
一句話記住:
當資料數量可能增加或刪除時,
List<T>可以讓我們更方便地管理一組指定 Type 的資料。