藉由 Codewars 來熟悉 C# 語法特性

2020-07-13

為了要讓自己能夠更熟悉 C# 的語法特性,決定複製自己學習 Python 的經驗,在 Codewars 上專門以 C# 來解決 Kata (題目),並從社群的 Solution 反饋自己值得學習的語法特性並整理成重點筆記。

logo
Codewars Csharp 目前的 Badge

重點筆記

Enumerable.Select

Select 作為 Map 的用法

類似於 Python 及 js 中的 Map,Select 可以將序列 (sequence) 中的元素經由統一處理而形成新的值。

using System.Linq;

var numberList = new List<int> { 1, 2, 3, 4, 5 };
var numberArray = new int[] { 1, 2, 3, 4, 5 };

Console.WriteLine(string.Join(",", numberList.Select(i => i * 2)));
// 2, 4, 6, 8, 10
Console.WriteLine(string.Join(",", numberArray.Select(i => i * i)));
// 1, 4, 9, 16, 25

Select 建構 匿名集合的用法

這種用法比較常用在從 Model 的類別中要擷取部分的 Property 另外構成匿名類型的集合時使用。

public class Person
{
    public string Name { get; set; }
    public DateTime BirthDate { get; set; }
    public string NickName { get; set; }
}

var userList = new List<Person> {
    new Person { Name = "sdwh", BirthDate = new DateTime(2020, 7 , 13), NickName = "hwds" },
    new Person { Name = "ryan", BirthDate = new DateTime(2019, 7 , 13), NickName = "nayr" },
};

var newUserList = userList.Select((user, index) => new { index, userFullName = $"{user.Name}, {user.NickName}" });

foreach (var user in newUserList)
{
    Console.WriteLine(user.userFullName);
}

Enumerable.Range

如同 Python 的 range ,可以產生連續的數值,不過只有一種建構的情形即 Range(start, count) ,如果要跳值產生的話需要另外的處理。

foreach (var num in Enumerable.Range(1, 5))
{
  Console.Write(num);
}
// 12345

Enumerable.Repeat

用來重複元素,可以用來重複 字元字串數字物件 等。

Console.Write(String.Concat(Enumerable.Repeat("c#", 3)));
// c#c#c#
Console.Write(String.Join(", ", Enumerable.Repeat("c#", 3)));
// c#, c#, c#

🤖 同場加映:也可以使用 new string(char, count) 建構子的方式來重複字元,但使用的彈性不如 Enumerable.Repeat 大。

Enumerable.Count

值得說明的是 Count 本身就支援篩選條件,不需要先 Where 後再做 Count

var intArray = new int[] { 2, 4, 6, 8, 10 };
Console.WriteLine(intArray.Count(i => i >= 6)); //✔️
Console.WriteLine(intArray.Where(i => i >= 6).Count()); //❌

Enumerable.Sum

Sum 的多載方法支援直接對 sequence 中的值做 Map 運算,但無法用來篩選條件,篩選仍必須搭配 Where 使用。

var intArray = new int[] { 2, 4, 6, 8, 10 };
Console.WriteLine(intArray.Sum(i => i * 2));
Console.WriteLine(intArray.Where(i => i <= 6).Sum());

Regex

移除字首字尾字元

using System.Text.RegularExpressions;
Regex.Replace(str, @"^.|.$", "");

字串比較 \z 連換行符號都要加入考慮

Regex.Match("1\n", @"^\d\z").Success // false
Regex.Match("1\n", @"^\d$").Success // true

Misc

Char IsDigit / IsLower / IsUpper / ToLower / ToUpper

C# 中 charstring 關係若即若離,有自己的 Property 和 Method ,儘管很相似,但終究是不太一樣的存在意義。


持續編輯中 👨‍🔧

相關連結