讀《先問為什麼》

如果你樂於接納新事物,希望成功能持久,也相信自己的成功需要別人的幫助

我向你提出一個挑戰 ——

從今天起,做任何事情之前,請先問自己「為什麼」。

這本書的中文副標很好地點出了本書的重點:顛覆慣性思考的黃金圈理論,啟動你的感召領導力。大多篇幅用在舉例以及逐步說明何謂感召,以及黃金圈。

本書的想法和一些例子,尤其是書中最重要的黃金圈理論,在作者上 TED 的影片「偉大的領袖如何鼓動行為」都有說明,有興趣的朋友可以直接看演講影片,足夠掌握到黃金圈理論的核心。

(偉大的領袖如何鼓動行為 - TED)

……

閱讀全文



C#: 時區轉換、民國西元、國曆農曆、中文月份週期

聊到將時間從 UTC 轉到台灣時間,居然還是聽到朋友表示使用 +8 小時的做法,驚為天人。這種做法可能會造成後續的問題,例如時區並不會跟著變動,或是遇到日光節約等特殊狀況就容易出事。和西元民國轉換直接 -1911 一樣不穩定。

這篇就用來記錄一下之前看過比較優雅的時區轉換方式,順便將先前存著的時間處理相關資料整理一下,方便之後需要時可以馬上回來查詢。

TimeZoneInfo: 時區資訊

轉換方式主要參考自 [食譜好菜] DateTime 具有文化特性的格式化及時區的轉換在各時區間轉換時間,感謝前人的指引。

關於文化特性,也可以參考本站的 菜雞抓蟲: DateTime.ToString() 之我們不一樣 & CultureInfo 文化特性小筆記 呦。

// 假設現在是要從標準時區 +00:00 轉換到台灣時區,故這邊使用 UtcNow 先取標準世界協調時間
var nowDateTime = DateTime.UtcNow;

nowDateTime.ToString("yyyy/MM/dd H:mm:ss zzz").Dump();
// 2020/08/30 15:56:05 +00:00

// ==================================================

// 傳統的 直接對時間做計算的方式…
var addedDateTime = nowDateTime.AddHours(8);

addedDateTime.ToString("yyyy/MM/dd H:mm:ss zzz").Dump();
// 2020/08/30 23:56:05 +00:00
// 可以看到儘管時間變動了,時區仍然還在 +00:00

// ==================================================

// 使用 TimeZoneInfo 先取得台北時區
var timeZone = TimeZoneInfo.FindSystemTimeZoneById("Taipei Standard Time");

// 再使用 TimeZoneInfo 來變更時間
var convertedDateTime = TimeZoneInfo.ConvertTime(nowDateTime, timeZone);

convertedDateTime.ToString("yyyy/MM/dd H:mm:ss zzz").Dump();
// 2020/08/30 23:56:05 +08:00
// 可以看到除了時間變更以外,時區也切換到 +08:00 了!

上面取得台北時區的步驟,可以參照 Time Zone IDs 來查詢想要的時區。這樣的時區切換方式,不僅副作用少,不會因為時區沒轉雷到後續接手的人,也省卻了擔心日光節約等等問題,這種事就交給微軟去煩惱吧!

……

閱讀全文



Powershell 美化作戰 —— 字型、執行原則和 oh-my-posh

最近在兩天內經歷了記憶體死去、系統毀損、機殼碎裂等等,終於電腦重灌。一堆設定都要重弄,正好也是個機會,這篇順手記一下常用好幫手 Powershell 的美化步驟。

先放一張施工後的圖鎮樓:

可以在開始圖示上用右鍵打開選單,之後點選 Powershell;或是 Win + X 打開選單,然後按 I 或 A (後者會以系統管理員身分開啟)就能開啟了。

如果選單打開還是 CMD 而不是 Powershell 的,可以先去切換成 Powershell,真的是比較好用啦(Windows Terminal 笑而不語)

剛打開的畫面是這樣的:

抱歉,光細明體我就不太行了。所以接下來就從字型這些內建設定開始!

……

閱讀全文



C#: 字串插值 (String interpolation) 的格式化

自從 C# 有了 字串插值 這東西之後,我就一直是愛用者。畢竟比起 string.format 這東西可是看起來優雅多了。例如:

var message = $"哈囉,{userName} 您的點數將於 {cutoffTime} 到期。";

簡潔又明瞭,一眼就能理解字串內容。實在是挺方便,後來發現這東西還有一些延伸用法,這邊就稍加紀錄一下:

字串插值中能夠做簡易計算,例如:

var message = $"您輸入的數值為:{a}、{b}。他們相加為:{a + b}";

同時,在字串插值時可以針對內容作格式化,只需要用 : 來區隔,妥善運用可以省下一堆 ToString() 的空間。

例如當我們要將時間格式化的時候,就可以:

var date = new DateTime(2020, 8, 9);
var message = $"您的商品已於 {date:yyyy/MM/dd} 抵達。";
// 您的商品已於 2020/08/09 抵達。

另外,數值當然也可以格式化,不過數值的應用比較複雜,主要是用來定下小數點、百分比等符號的位置。 可以參見 自訂數值格式字串 - Microsoft Docs

var cost = 2100;
var message1 = $"您的商品一共是 {cost:#,###} 元";
// 用 # 可以替數字預留位置
// 您的商品一共是 2,100 元

var message2 = $"您的商品一共是 {cost:#,###.00} 元";
// 也可以用 0 來預留位置,若該數字有值就會顯示該數字,沒有就會自動補 0
// 您的商品一共是 2,100.00 元
……

閱讀全文



C#: 使用 System.Environment 取得環境資訊、特殊資料夾路徑

有時候我們會需要取得一些系統資訊,例如說取得設備和當前使用者等資料來寫 Log,或是取得特殊資料夾路徑、讀取環境變數等等。這些時候就可以使用 System.Environment ,這邊就稍微紀錄一下用法。

先列出幾個常用的環境資訊,詳細可查詢的內容可以到 Environment Class 查詢:

資料夾路徑則需要用 Environment.GetFolderPath 搭配 Environment.SpecialFolder 列舉使用,該列舉包含資料夾可以到 Environment.SpecialFolder Enum 查詢。

……

閱讀全文



C#: 程式碼風格備忘

前言:本篇是整理公司規範和網路文章後,方便我自己在各個場所也能回來查閱使用的,故仍會不定時修改(畢竟我這人挺三心二意的)。另外本篇有重新調整過行距,發現有點跑版的朋友可以先 Ctrl+F5 一下,感謝閱讀。

如果你想知道的是如何寫出更優雅、更乾淨、品質更高的程式碼,那並不是該看這篇我個人的備忘錄,我會建議可以閱讀《無暇的程式碼》。或是可以參考這幾篇,我覺得都寫得很好:可不可以不要寫糙 codeClean Code 無瑕的程式碼閱讀筆記易讀程式之美學,共勉之。

如果你是正巧路過並且也寫 C#,希望這篇能讓你做為參考。但請記得,程式碼風格沒有絕對,最終還是回歸到團隊能否接受和將來的可維護性去考慮,畢竟教條是死的,人是活的。了解這樣做背後的原因,以及為自己寫的程式碼負責,這些都比對著隻字片語斤斤計較更加重要。

Nothing is true, everything is permitted. —— Assassin’s creed.

2025.01.03 補充:
剛好看到保哥分享了他們家的 C# 程式碼撰寫規範,有需要的朋友也可以作為參考

命名原則

想像下一個接手你程式碼的人是個暴力傾向的重度精神病患者

而且他知道你住在哪。  —— 《無瑕的程式碼》

  • 使用有意義的命名,請重視描述性。除了迴圈計數器例外
  • 盡量不要超過五個單字
  • 業界和慣例中有對應縮寫時可以使用縮寫
  • 承上,縮寫兩個字母時全大寫,三個字母以上時只第一字大寫

命名空間

  • 基礎類別庫:{組織} . {大類/應用範圍} . {小類/專案名稱}
    • MyStudio.Libs.Basic
    • MyStudio.Libs.Web.BaseTools
  • 專案類別庫:{專案名稱} . {子專案/類別/用途}
    • MyProject.Permiss.Proxy
    • MyProject.Permiss.Repository
……

閱讀全文



Pocket —— 稍後閱讀,想看再看

前言:由於我這人特喜歡發完文之後一想到就回去改改,因此現在還在修改上一篇物件導向的內容囧。講好聽是有持續交付的精神,講難聽就是比較後知後覺一點。因此這幾篇仍會像之前我要買便當系列一樣,主軸間穿插個幾篇小工具或心得,以這個節奏前進。所以這邊就介紹一下我幾乎每天都會用到的小工具:Pocket

在兩個多月前,我們介紹過將文章用 RSS 訂閱集中起來的工具 Feedly。但是,有些時候雖然對文章挺有興趣的,但並不適合馬上看(例如在公司或學校的時候,看到社論、科技新聞等等);或是像我個人平常休息時逛逛一些論壇或是文檔,這時候如果遇到一些比較長的、主題式的文章,就會想要把文章存放起來,等晚些時候再看。

雖然 Feedly 也有提供 Read Later 的功能,只要勾個標籤就可以之後再到 Read Later 的頁面去觀看。但懶惰如我,就會想要把所有稍後再看的文章集中在一塊,因此必須尋找一個前述場景都共用的做法,這時我就遇上了 Pocket。

Pocket 是一個簡單直接的「稍後閱讀」服務,操作方便,只需要擴充套件或分享,和一段能靜下來好好閱讀的時間即可服用。在開始介紹之前,有幾件事必須報告:

……

閱讀全文



菜雞與物件導向 (7): 介面

如果說繼承是用來表明物件「屬於什麼」;那麼介面就是用來表明物件「能做什麼」。

如果說封裝是將物件視作一個整體,是隱藏複雜度;那麼介面就是封裝精神的體現。

如果說多型是指藉著繼承後能實作不同的行為的可能性達到擴展的彈性;那麼介面就是在實作多型。

介面就是這麼厲害,這麼瀟灑。介面就是我大哥,今天誰不服介面,對不起!我們不認識。

介面就像是針對類別的實作、物件的行為去做規定的一個契約書,會先定義好要實作這個介面的類別所必須要有的方法,而當我們建立符合這個介面的類別時,就必須實作出所有介面中定義好方法才可以。……這樣說起來實在太繞口,總而言之介面的核心概念只有一條:

我不在乎你是誰,我只在乎你能做什麼。

還是公司誠徵工程師的例子

由於介面基本上就是封裝繼承多型抽象之大雜燴,所以我們把前面多型的小明小華例子稍微修改來用吧。也就是以公司徵人的方式去理解介面。

介面就像是老闆開出來的要求列表,例如說:要會寫 C#、要會寫 SQL、要會 VB…等等,於是老闆就貼出了徵人啟示,要求新來的員工必須要有 IProgrammer 寫的能力:

public interface IProgrammer
{
    void WriteCSharp();
    void WriteSQL();
    void WriteVB();
}

特別注意和前面多型的例子的不同處,介面只需要先定義好該做的事,裡面怎麼做不需要管;所以只需要宣告要求的方法,不需要撰寫方法本體

於是今天小華就又(?)來面試了,但是他其實並不會寫 C#:

public class Hua : IProgrammer
{
    // Error: Hua 未實作 IProgrammer.WriteCSharp()

    public void WriteSQL() { /* Work */ }
    public void WriteVB() { /* Work */ }
}

這時候編譯器就會跳出錯誤了:很抱歉,你不符合我們 IProgrammer 的規定,因為我們只喜歡訓練精英(略),請你實作完之後再來。否則你就不能掛上我們 : IProgrammer 的頭銜。

……

閱讀全文



菜雞與物件導向 (6): 抽象、覆寫

備註:這邊的抽象是指程式語言中的抽象類別,而非抽象化

抽象的概念很直接,請回想一下前面的例子就可以了:

當我們在用卡牌的例子時,雖然怪獸卡跟魔法卡都繼承了 Card 這個類別,但是我們仍然能
new Card() 來建立一張新卡牌,那…怪怪的吧,這張卡牌到底是什麼呀,空白的卡片嗎?

又或是動物的例子,我們的狗跟貓都繼承了哺乳類,那我們能實例化一個哺乳類嗎?我們的狗跟鳥都是動物,那我們能實例化一個動物嗎?

小明跟小華都繼承了工程師,那我們能 new 一個工程師嗎…?

有些類別就是這樣,它們負責定義共通的那些特性,然而它們本身不應該被實體化成一個物件,這種類別我們就應該把它們標記為抽象類別

抽象類別在 C# 裡用 abstract 這個修飾詞來表示,可以加在類別或方法上。例如 abstract class Animal 就代表動物這個類別是個抽象類別,它不能被實例化。

而當加在方法上時,例如 public abstract void Eat() 就是代表這個進食的方法無法被叫用,只能由繼承者去重新定義這個方法。

abstract class Animal
{
    public string color { get; set; }
    public abstract void Eat();
}

那麼繼承者們,也就是衍生類別如何去重新定義父類別的方法呢?

所謂「欲戴王冠,必 Override」,這時候就必須使用覆寫(override

覆寫是指對於像是前述的抽象方法時,在同名的方法前加上 override 關鍵字就可以讓程式知道你要覆寫這個方法(你不覆寫的話,編譯器還會生氣)。

例如前述的 Eat,狗就可以用 public override void Eat() 的方式去覆寫吃東西這個方法:

public class Dog : Animal
{
    public string color { get; set; } = "Black";
    public override void Eat()
    {
        /* 嚼嚼嚼 */
    }
}
……

閱讀全文



菜雞與物件導向 (5): 多型

多型算是比較三特性之中給人感覺比較溫和的了,不如說只要有了繼承,那麼多型的到來就是必然的。多型的定義是:不同的物件能夠做出一樣的行為,但必須由他們自己的程式碼來實作。

白話一點說就是:一樣的事,不同做法

多型相對是比較好理解的,畢竟每個人做同一件事的方法本來就不太一樣。例如一樣是泡奶茶,英國就正常地泡,美國就會用微波爐;一樣是肉粽,有些人就是比較愛吃油飯;到了程式的世界裡也是,即使繼承了同一個物件,實現這個行為的方式也可以不同。

在此可以先推菜鳥工程師肉豬的這篇 Java 什麼是多載(Overload), 覆寫(Override), 多型(Polymorphism) 中的說明。其中可以從例子看到儘管狗跟鳥都是繼承自動物這個類別,但對於「移動」這個方法,他們實作的方式並不一樣。這就是多型的範例。

我個人更喜歡用職位的方式去理解多型。

被繼承者就像是該職位的工作,例如說:Programmer 要會寫 C#、要會寫 SQL、要會 VB…等等,於是老闆就貼出了徵人啟示,要求新來的員工必須要有 Programmer 寫的能力:

public class Programmer
{
    public virtual string WriteCSharp()
    {
        /* 努力地寫 C# */
    }
    public virtual string WriteSQL()
    {
        /* 努力地寫 SQL */
    }
    public virtual string WriteVB()
    {
        /* 努力地寫 VB */
    }
}
……

閱讀全文



系列文

轉貼文

最近文章

分類

標籤

友鏈

統計資訊

工商服務

    DDDTaiwan