# C#(Sharp)
###### tags: `講義` `C#`
# 物件導向程式設計
僑光科技大學 資訊科技系
授課老師:[高吉隆](http://rs2.ocu.edu.tw/~kevin/)
電子信箱:[kevinkao888@gmail.com](mailto://kevinkao888@gmail.com)
上課日期:108/02/18 ~ 108/06/17
上課時間:星期一 09:10 ~ 12:00
---
## 課程大綱
* Visual Studio C#
* 程式偵錯、變數監看
* C#程式的變數、流程控制
* C#程式的陣列、字串
* C#程式的類別、物件
* C#程式的方法、引數傳遞
* C#程式的繼承、泛型
* C#程式的專題實作
----
### 每週上課目標
* 前 9 週上課目標
* 觀念講解、小考測驗
* 上課練習、期中測驗
* 後 9 週上課目標
* 分組討論、規劃報告
* 專題實作、成果報告
----
| 週| 上課日期 | 前 9 週上課目標 | 備註
|:-:|:---------:|------------|:--:
| 1 | 108/02/18 |課程設計與簡介|
| 2 | 108/02/25 |變數、流程控制|
| 3 | 108/03/04 |陣列、字串|
| 4 | 108/03/11 |主控台程式實作|
| 5 | 108/03/18 |類別、物件|
| 6 | 108/03/25 |方法、引數傳遞|
| 7 | 108/04/01 |繼承、泛型|小考10%
| 8 | 108/04/08 |Windows/Web實作|
| 9 | 108/04/15 |期中測驗|30%
----
| 週 | 上課日期 | 後 9 週上課目標 | 備註
|:--:|:----------:| --------------- |:--:
| 10 | 108/04/22 | 人員分組與題目訂定 |
| 11 | 108/04/29 | 專題規畫、版面設計 |
| 12 | 108/05/06 | 書面資料、功能分析 |
| 13 | 108/05/13 | 問題討論、解決 |
| 14 | 108/05/20 | 程式設計、結果測試 |作業10%
| 15 | 108/05/27 | 書面資料之分組報告 |
| 16 | 108/06/03 | 上機操作與問題解決 |
| 17 | 108/06/10 | 成果展示之簡報製作 |平時10%
| 18 | 108/06/17 | 期末專題成果展示 |30%
----
### 課程評分方式
* 平時成績:30% (上課互動+二次小考)
* 上課互動:10% (10次點名)
* 第一次小考:10% (108/03/18) C#程式基礎
* 第二次小考:10% (108/04/08) C#物件導向
* 期中成績:30% (108/04/15)
* 考試範圍:C#程式基礎 物件導向
* 期末成績:40% (期末報告)
* 第一次作業:10% (108/05/27) 書面報告
* 專題製作:30% (108/06/17)上台報告、PPT簡報
----
### 使用教科書
* 書名:從零開始學Visual C# 2015/2017程式設計
* 出版社:博碩文化
* 作者:李馨
![](https://im2.book.com.tw/image/getImage?i=https://www.books.com.tw/img/001/079/59/0010795909.jpg&v=5b6ac654&w=348&h=348)
----
### 第一次小考
* 調分:有2小題答案有2個,答正確給4分
* 加15分,加分後最高分:99,平均:61
![](https://i.imgur.com/eKR70z2.png)
----
### 期中考
* 調分:有1小題答案有2個,答正確給3分
* 加25分,加分後最高分:99,平均:68
![](https://i.imgur.com/No11Y35.png)
----
### 期末報告
* HACKMD:[連結](https://hackmd.io/s/HJo3lL82N)
----
### 網路資源
* 網站:W3Schools
* 網址:[https://www.w3schools.com/asp](https://www.w3schools.com/asp/default.asp)
* 主題:ASP C#
----
## 認識C#程式語言
* 微軟在2000年發布了這種語言
* 一種基於.NET框架(Framework)的程式語言
* 支援物件導向的一種進階程式語言
* 擁有類似Visual Basic的快速開發能力
* 微軟希望藉助這種語言來取代Java
* C#的發音為「C sharp」
* 命名啟發於音樂上的音名「C#」
* C#旨在設計成為一種「簡單、現代、通用」
----
|類型|C++|C#|
|-|-|-|
|語言等級|低階|高階|
|編譯|機器語言|CLR中繼語言|
|記憶體管理|手動|自動|
|是否可獨立執行|是|否|
|支援物件導向|不完整|完全|
|陣列邊界檢查|否|是|
|支援垃圾收集|否|是|
|支援ForEach|否|是|
----
### C#的HelloWorld程式範例
```csharp
using System;
public class HelloWorld {
public static void Main(string[] args) {
Console.WriteLine("Hello world!");
Console.ReadLine();
}
}
```
----
## C#的開發環境
Visual Studio Community
* [官方連結](https://visualstudio.microsoft.com/zh-hant/vs/community/):可免費下載使用
* 功能齊全且可擴充的免費 IDE
* 可建立 Windows 版、 Web 應用程式
* 可建立 Android 版、iOS 版手機程式
* 設計工具、編輯器、偵錯工具和分析工具在一起
* 程式撰寫時有即時自動完成之提示選擇
* 支援C#、VB、F#、C++、HTML、JavaScript、TypeScript、Python 等
* 支援 Microsoft .Net FrameWork元件
----
![](https://i.imgur.com/iSxFlVW.png)
---
## C#的型別與變數
* 實值型別(Value),存放數值的變數(Variables)
* 分為簡單、列舉、結構、可為null的變數
* 簡單:
* 帶正負整數:sbyte、short、int、long
* 不帶正負整數:byte、ushort、uint、ulong
* Unicode字元:char
* 浮點數:float、double
* 高精確度十進位:decimal
* 布林值:bool
* 列舉:enum E {...}
* 結構:struct S {...}
----
## C#的型別資料範圍
|型別|範圍|大小
|:-:|:-:|:-:|
|sbyte|-128 ~ 127|8bit
|byte |0 ~ 255|8bit
|short|-32,768 ~ 32,767|16bit
|ushort|0 ~ 65,535|16bit
|int|-2,147,483,648 ~ 2,147,483,647|32bit
|uint|0 ~ 4,294,967,295|32bit
|float|-3.4x10^38^ ~ 3.4x10^38^|32bit
----
## C#的型別與變數
* 參考型別(Reference),由類別產生之物件(Objects)
* 分為類別、介面、陣列、委派
* 類別:
* 基底類別:object
* Unicode字串:string
* 使用者定義類別:class C {...}
* 介面:interface I {...}
* 陣列:int[]、int[,]
* 委派:delegate int D(...)
----
## C#的變數宣告、運算式
* 區域變數宣告:int a;
* 區域常數宣告:const float pi = 3.14;
* 運算陳述式:i = 123;
* 運算式:運算元+運算子
* 主要運算式:
* 成員存取:.
* 方法叫用:(...)
* 陣列存取:[...]
* 建立物件、初始設定:new T(...){...}
----
## C#的各種運算子
* 算述:+, -, *, /, %(餘數)
* 關係:==, !=, >, <, >=, <=
* 邏輯:&&, ||, !
* 位元:&, |, ^, ~
* 位移:>>, <<
* 複合指定:=, +=, -=, *=, /=
* 後置遞增、後置遞減:x++、x--
* 前置遞增、前置遞減:++x, --x
----
## C#的流程控制 IF
* if 陳述式一:if () {}
* if 陳述式二:if () {} else {}
* if 陳述式三:if () {} else if () {} else {}
```csharp=
if (B < 18.5) {
...
} else if (B < 24) {
...
} else if (B < 27) {
...
} else {
...
}
----
## C#的流程控制 switch
* switch:
```csharp=
switch (variable)
{
case value1:
...
break;
case value2:
...
break;
default:
...
}
```
----
## C#的函數 function
```csharp=
函數類別 回傳值型別 函數名稱 (參數型別 參數名稱) {
函數內容
return 回傳值;
}
```
```csharp=
private string BMI2LevelString(float BMI) {
string LevelString = "";
if (BMI < 18.5) {
LevelString = "過輕";
} else if (BMI < 24) {
LevelString = "正常";
} else if (BMI < 27) {
LevelString = "過重";
} else if (BMI < 30) {
LevelString = "輕度肥胖";
} else if (BMI < 35) {
LevelString = "中度肥胖";
} else {
LevelString = "重度肥胖";
}
return LevelString;
}
```
----
## C#的陣列 Array
* 陣列定義
```csharp=
元素型別[] 陣列名稱 = {元素1, 元素2, ...};
```
* 實際範例
```csharp=
string[] BMILevelString = new string[] {"過輕", "正常", "過重", "輕度肥胖", "中度肥胖", "重度肥胖"};
string LevelString1 = BMILevelString[0];
int[] BMILevelNo = {0, 1, 2, 3, 4, 5};
int LevelNo2 = BMILevelNo[1];
float[] BMILevelMax = {18.5, 24, 27, 30, 35, 99};
float LevelMax3 = BMILevelMax[2];
```
---
### 課堂練習一:BMI基本計算(BMI)
* 使用者輸入身高(公分)、體重(公斤)
* 計算出BMI=體重(公斤)/身高(公尺)平方
![](https://pic.pimg.tw/isvincent/4b5339bd3f26d.png?v=1263745469 =800x400)
----
## C#的Windows Form應用程式
* 打開 Visual Studio 2017
* 新增專案範本:Visual C#->Windows Form App
* 建立專案名稱:BMI
* 選擇位置:D:\BMI\
![](https://i.imgur.com/HygTCxF.png =800x400)
----
## C#的Form類別
* 開始執行:Play鍵
![](https://i.imgur.com/SA1iaQb.png =300x150)
* 視窗基本功能:
* 關閉:程式會關閉,並結束程式
* 視窗最大化:將視窗放大至全螢幕
* 視窗最小化:將視窗縮小至工具列
* 強制中斷:Stop鍵
----
## C#的Form屬性
* Name:視窗的名稱
* Text:視窗的標題
* ForeColor:視窗的文字顏色
* Font.Size:視窗的文字大小
* Size.Width:視窗的大小之寬度(像素)
* Size.Height:視窗的大小之高度(像素)
* ControlBox:是否顯示視窗的控制項
* ShowIcon:是否顯示視窗的小圖示
----
## C#的Button類別
* 建立按鈕:
![](https://i.imgur.com/6qIdYxH.png =300x150)
* 選擇工具箱->通用控制項->Button
* 於視窗編輯區拉出按鈕物件
* 改變按鈕屬性內容:
* Text:計算
* Font.Size:20
----
## C#的TextBox類別
* 建立輸入盒:2個
![](https://i.imgur.com/blVh4HB.png =300x150)
* 選擇工具箱->通用控制項->TextBox
* 於視窗編輯區拉出TextBox物件
* 改變TextBox屬性內容:
* (Name):Height、Weight
* Font.Size:20
----
## C#的Label類別
* 建立標籤:
![](https://i.imgur.com/adVihZb.png =300x150)
* 選擇工具箱->通用控制項->Label
* 於視窗編輯區拉Label物件
* 改變Label屬性內容:
* (Name):BMI
* Text:BMI
* Font.Size:20
----
## C#的Button事件
* 建立Button事件:於按鈕上用滑鼠連按二下
* 於 button1_Click 事件程式碼中輸入
```csharp=
private void button1_Click(object sender, EventArgs e) {
float W = float.Parse(Weight.Text);
float H = float.Parse(Height.Text) / 100;
float B = W / H / H;
BMI.Text = B.ToString("BMI: ##.0");
}
```
* 使用 float.Parse 函數強制轉變型別
* 使用 .ToString 函數將浮點數轉換為數字
----
### 流程圖
```flow
st=>start: 開始
e=>end: 結束
input=>subroutine: 輸入身高體重
calc=>operation: 計算BMI值
st->input->calc->e
```
----
### 程式碼:計算BMI
```csharp=
namespace BMI
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
float W = float.Parse(Weight.Text);
float H = float.Parse(Height.Text) / 100;
float B = W / H / H;
BMI.Text = B.ToString("BMI: ##.0");
// 輸入判斷結果
}
}
}
```
----
## C#的程式碼:判斷結果
```csharp=
if (B < 18.5) {
Level.Text = "過輕";
} else if (B < 24) {
Level.Text = "正常";
} else if (B < 27) {
Level.Text = "過重";
} else if (B < 30) {
Level.Text = "輕度肥胖";
} else if (B < 35) {
Level.Text = "中度肥胖";
} else {
Level.Text = "重度肥胖";
}
```
----
## C#函數:BMI轉換成文字結果
* 函數名稱:BMI2LevelString
* 輸入值:BMI數字
* 輸出值:LevelString文字
```csharp=
private string BMI2LevelString(float BMI) {
string LevelString = "";
if (BMI < 18.5) {
LevelString = "過輕";
} else if (BMI < 24) {
LevelString = "正常";
} else if (BMI < 27) {
LevelString = "過重";
} else if (BMI < 30) {
LevelString = "輕度肥胖";
} else if (BMI < 35) {
LevelString = "中度肥胖";
} else {
LevelString = "重度肥胖";
}
return LevelString;
}
```
----
## C#按鈕事件:將判斷寫成函數一
* 將BMI值轉換成判斷結果文字
```csharp=
private void button1_Click(object sender, EventArgs e) {
float W = float.Parse(Weight.Text);
float H = float.Parse(Height.Text) / 100;
float B = W / H / H;
BMI.Text = B.ToString("BMI: ##.0");
Level.Text = BMI2LevelString(B);
}
```
----
## C#函數:BMI轉換成數字結果
* 函數名稱:BMI2LevelString
* 輸入值:BMI數字
* 輸出值:LevelNo數字
```csharp=
private int BMI2LevelNo(float BMI) {
int LevelNo = -1;
if (BMI < 18.5) {
LevelNo = 0;
} else if (BMI < 24) {
LevelNo = 1;
} else if (BMI < 27) {
LevelNo = 2;
} else if (BMI < 30) {
LevelNo = 3;
} else if (BMI < 35) {
LevelNo = 4;
} else {
LevelNo = 5;
}
return LevelNo;
}
```
----
## C#按鈕事件:將判斷寫成函數二
```csharp=
private void button1_Click(object sender, EventArgs e) {
float W = float.Parse(Weight.Text);
float H = float.Parse(Height.Text) / 100;
float B = W / H / H;
BMI.Text = B.ToString("BMI: ##.0");
int L = BMI2LevelNo(B);
switch (L) {
case 0:
Level.Text = "過輕"; break;
case 1:
Level.Text = "正常"; break;
case 2:
Level.Text = "過重"; break;
case 3:
Level.Text = "輕度肥胖"; break;
case 4:
Level.Text = "中度肥胖"; break;
case 5:
Level.Text = "重度肥胖"; break;
default:
Level.Text = ""; break;
}
}
```
----
## C#按鈕事件:將判斷寫成函數,再用陣列完成
```csharp=
private string[] LevelString = new string[] {"過輕", "正常", "過重", "輕度肥胖", "中度肥胖", "重度肥胖"};
private void button1_Click(object sender, EventArgs e) {
float W = float.Parse(Weight.Text);
float H = float.Parse(Height.Text) / 100;
float B = W / H / H;
BMI.Text = B.ToString("BMI: ##.0");
int L = BMI2LevelNo(B);
Level.Text = LevelString[L];
}
```
----
## C#程式範例參考-1
* 進度:
1. 進立Form1中所有元件:標籤、文字輸入、按鈕
2. 修改標籤及按鈕的Text屬性
3. 修改所有元件的名稱
4. 增加按鈕的事件
5. 宣告各級數文字的陣列
6. 宣告計算BMI數值函數
7. 宣告判斷BMI級數函數
* [BMI-1下載](http://rs2.ocu.edu.tw/~kevin/BMI-1.zip)
----
## C#程式範例參考-2
* 進度:
1. 建立Form1中元件:圖片
2. 設定圖片元件的Image屬性
3. 宣告各級數圖片的名稱為陣列
4. 改變判斷BMI級數函數為迴圈
* [BMI-2下載](http://rs2.ocu.edu.tw/~kevin/BMI-2.zip)
---
## C#物件導向概念
* 類別Class:
* 抽象的資料型別
* 含資料Data、方法(Method)及事件(Event)
* 資料成員:定義在類別中的型別即是欄位資料
* 方法成員:定義在類別中的函數即是方法成員
* 工具箱中的TextBox、Button即是類別Class
* Button中的Text屬性即是欄位資料
* Button中的Hide函數即是方法成員
* Button中的Click函數即是事件
----
## C#自行定義類別
* 類別名稱:student(學生)
* 欄位名稱:height(身高)(公分)
* 欄位名稱:weight(體重)(公斤)
* 方法名稱:BMI
```csharp
public class student {
public float height;
public float weight;
public float BMI() {
return weight / (height / 100) / (height / 100);
}
}
```
----
## C#範例三-使用類別計算BMI
* 建立按鈕:button2
* 在button2_click事件加上程式
```csharp
private void button2_Click(object sender, EventArgs e) {
Student student1 = new Student();
student1.height = float.Parse(Height.Text);
student1.weight = float.Parse(Weight.Text);
BMI.Text = student1.BMI().ToString("BMI: ##.0");
}
```
----
## C#定義類別之存取範圍
* public:未限制存取
* 即外面的類別都可以直接存取
* private:存取限於包含類型
* 即僅內部的類別才可以存取
* protected:存取限於包含類別或衍生自包含類別的類型
* 即僅內部及衍生類別才可以存取
----
## C#將內部變數改為屬性型別
```csharp
private float height = 0; // 身高欄位
private float weight = 0; // 體重欄位
public float Height { // 宣告屬性名稱
get { return height; } // 回傳屬性值
set { height = value; } // 設定屬性值
}
public float Weight { // 宣告屬性名稱
get { return weight; } // 回傳屬性值
set { weight = value; } // 設定屬性值
}
```
----
## C#的陣列
* 陣列的意義:
* 陣列的宣告、配置、設定:
* 陣列的讀取:
----
### C#陣列的意義
* 什麼是變數?答:一個儲存資料的容器
```csharp=
int math = 80; // 將 80 儲存在名稱為 math 的整數變數中
int eng = 90; // 將 90 儲存在名稱為 eng 的整數變數中
```
* 陣列是一種特殊的變數:可以一次儲存多個資料的容器
```csharp=
// 標準寫法:把80和90存入名稱為score1,元素為2個整數的陣列中
int[] score1 = new int[2] {80, 90};
int[] score2; // 分解動作:1(宣告).先宣告一個整數陣列
score2 = new int[2]; // 2(配置).配置2個整數空間給陣列
score2[0] = 80; // 3(設定)-1.再將80存入第1個元素
score2[1] = 90; // 3(設定)-2.再將90存入第2個元素
```
----
### C#陣列的宣告、配置、設定
* 使用陣列三步驟:宣告、配置、設定
* 宣告:宣告陣列變數
* 為陣列變數取名稱
* 必需指定元素的型別,並加入中括號[]識別
* 配置:配置記憶體
* 為陣列配置記憶體空間
* 必需加入new識別,並指定陣列的個數
* 設定:設定初始值
* 為陣列元素設定內容值
* 必需在中括號[]中指定放入第幾個元素
----
### C#陣列的讀取
* 使用for迴圈
```csharp=
int[] score1 = new int[2] {80, 90};
for (int i = 0; i < 2; i++) {
WriteLine($"{score1[i]}"); // 使用索引變數i來讀出
}
```
* 使用foreach迴圈
```csharp=
int[] score1 = new int[2] {80, 90};
foreach (int item in score1) {
WriteLine($"{item}"); // 使用內容變數item來讀出
}
```
----
## 物件導向BMI範例
* 建立類別
```=csharp
public class Person {
}
```
* 建立屬性
```=csharp
private float Height { set; get; } = 0;
private float Weight { set; get; } = 0;
```
* 檔案:[下載](https://my.ocu.tw/cs/BMI-3.zip)