本篇擷取重點:
我們在 上一篇 透析了主程式部分的程式碼,
這篇,我們將接著繼續進行 副程式(GetJsonContent)部分 的程式碼解析。
但在開始之前,我們要先來聊聊 什麼是副程式?
一、什麼是副程式?
==================================================================
貼心小補充:
本篇雖將 函式/方法 稱為 副程式 方便瀏覽者想像,但其實物件導向中沒有所謂的 "副程式" (routine) 的說法,可能要早點習慣用 "函式" (function) 或 "方法" (method) 的詞彙,因為有些 "副程式" 可以寫得跟 "主程式" 一樣 :),當然這是要適當規劃才會有這種情況,若是在同一個副程式中處理所有的事是不算的喔...
==================================================================
副程式名稱(參數1,參數2)
以本題為例,GetJsonContent為副程式名稱,丟進去的參數為那一串網址字串:
string content = GetJsonContent("https://www.ktec.gov.tw/ktec_api.php?type=json");
static void 副程式名稱(資料型態1 參數1,資料型態2 參數2)
{
程式區塊
}
// Note:這邊的參數可以是變數或陣列
以本題為例,因為丟入副程式的參數是一串網址字串,故須在副程式裡面建立一個 字串變數Url 來接。
private static string GetJsonContent(string Url)
{
程式區塊
}
static 靜態宣告,靜態方法在程式加載時就已經存在,故在使用前無需初始化(new)就能直接訪問。
void 沒有返回值宣告,也就是沒有return 關鍵字。
public / private / protected 皆是為了控制類別外部的存取權而設定的東西。
參考資料:
http://mermerism.blogspot.com/2014/04/blog-post_3.html -(更多 副程式 )
http://weisnote.blogspot.com/2012/08/static.html -(更多 static宣告 )
二、副程式(GetJsonContent)程式碼之解析
接下來進入副程式(GetJsonContent)之程式碼解析的部分
private static string GetJsonContent(string Url)
{
string targetURI = Url;
var request = System.Net.WebRequest.Create(targetURI);
request.ContentType = "application/json; charset=utf-8";
var response = request.GetResponse();
string text;
using (var sr = new StreamReader(response.GetResponseStream()))
{
text = sr.ReadToEnd();
}
return text;
}
因為在主程式引用GetJsonContent方法(副程式)時,丟入的參數是一串網址字串,故須在副程式裡面建立一個 字串變數Url 來接。(這裡設的變數名稱僅在此方法內使用,雖然怎麼命名並不會影響外面引用,但實務上還是會盡量讓變數名稱和方法內的參數相同,比較容易辨別,這是比較好的寫作習慣~)
感謝 YoChen 網友的觀念提供!
string targetURI = Url;
var request = System.Net.WebRequest.Create(targetURI);
設字串targetURL來接丟進副程式字串參數string Url。
設變數request來向targetURI網址送出請求,怎麼請求?
使用【System.Net命名空間】中的【WebRequest類別】的【create方法】來向【targetURI】請求
request.ContentType = "application/json; charset=utf-8";
告訴伺服器端,即將傳輸的請求資料的MIME類型
var response = request.GetResponse();
設變數response來接送出請求之伺服器之response。
string text;
using (var sr = new StreamReader(response.GetResponseStream()))
{
text = sr.ReadToEnd();
}
建立一個字串text,方便後面使用
利用response.GetResponseStream()方法,回傳來自網際網路資源的資料流(stream),並透過初始化StreamReader類別來從資料流中(Stream)讀取字元,最後再建立一個物件sr來接。
using 陳述式:在建立物件sr的當時,使用 using 陳述式,當這個區塊程式碼結束執行之後,能確保該物件所佔用的資源一定會被完整釋放。
ReadToEnd()方法是直接讀取資料流中,目前位置開始到整個資料流結束的所有字元,並且回傳string 型別結果字串,代入前面建立的字串text。
return text;
除非副程式有宣告void,不然該副程式必有回傳值。
以本題GetJsonContent副程式為例,副程式並未宣告void,故必定要有回傳值,
丟進去的參數:"https://www.ktec.gov.tw/ktec_api.php?type=json" (string Url)。
回傳值為:字串text
參考資料:
https://blog.miniasp.com/post/2009/10/12/About-CSharp-using-Statement-misunderstanding-on-try-catch-finally -(更多 Using 陳述句 )
http://www.kangting.tw/2019/06/stream_24.html -(更多 Stream-字元資料讀寫 )
今天的分享到這邊告一段落,
由於筆者也仍處在學習階段,如果有不正確的地方,也煩請指教,感謝各位大大!!
void 沒有返回值宣告,也就是沒有renturn 關鍵字。
使用【System.Net命名空間】中的【WebRequest類別】的【reate方法】來向【targetURI】請求
Return跟Create有錯字哦~XDDD
設成protected時,只有在同一個package或繼承該類別後才能夠存取
應該是只有繼承的子類別才能存取
因為在主程式引用GetJsonContent方法(副程式)時,丟入的參數是一串網址字串,故須在副程式裡面建立一個 字串變數Url 來接。(這裡設的變數名稱僅在此方法內使用,所以怎麼命名其實沒這麼重要,並不會影響外面引用)
實務上還是會盡量讓變數名稱和方法內的參數相同,比較容易辨別,這是比較好的寫作習慣~
string text;
using (var sr = new StreamReader(response.GetResponseStream()))
{
text = sr.ReadToEnd();
}
return text;
這一段可以簡化成
using (var sr = new StreamReader(response.GetResponseStream()))
{
return sr.ReadToEnd();
}
即使return過後,sr.Dispose()還是會被執行~
謝謝大大的錯誤更正及觀念提供,不過還想請問一下,當我們將該成員宣告成protected保護層級,不是可供自身類別(父類別)和衍生類別(子類別)存取該成員嗎?
protected可供自身類別(父類別)和衍生類別(子類別)存取該成員
沒錯哦~您說的是對的,是我表達得不夠完整~XDDD
設成protected時,只有在同一個package或繼承該類別後才能夠存取
但通常我們說的同一個Package,通常是說在同一個Namespace,畢竟他們最後都會被包在同一份dll中,如果以這樣的觀點出發,您在文中的描述就會有點問題~XDDD
了解,謝謝大大的詳細解釋!!
我也一直對這個Package的定義是什麼感到疑惑,所以才選擇直接貼上原文的說法XDD,馬上修改哈哈哈哈
收到,感謝幫助確立觀念,但若直接把文章內的副程式改成函式/方法,文章變得有點生硬難閱讀,所以我將大大整理的觀念放在文章最前頭的補充部分!