文章目錄
一:類和結構
類和結構其實就是實現對象的模板,每個對象都有數據和處理數據的方法。
類和結構的不同點:
a、類支持繼承,結構不支持繼承
b、類是引用類型,存儲在堆(heap)上,結構是值類型,存儲在棧(stack)上
c、類的關鍵字(class),結構的關鍵字(struct)。
示例1:
class PhoneCustomer
{
public const string DayOfSendingBill = "Monday";
public int CustomerID;
public string FirstName;
public string LastName;
}
兩者都是用new關鍵字創建並對其進行初始化
二:類
類包含成員,成員分爲靜態成員和實例成員。靜態成員屬於類,實例成員屬於對象。即靜態字段的值在每個對象中都是相同的,實例字段每個對象都可以有不同的值。靜態成員關聯了static修飾符
成員 | 說明 |
---|---|
字段 | 字段是類的數據成員,它是類型的一個變量,該類型是類的一個成員 |
常量 | 常量與類相關。編譯器使用真實值代替常量 |
方法 | 與特定類相關的函數 |
屬性 | 可以從客戶端訪問的函數組 |
構造函數 | 實例化對象是自動調用的特殊函數 |
索引器 | 允許對象用訪問數組的方式訪問 |
運算符 | 運算符執行的最簡單的操作就是執行加法和減法 |
事件 | 事件是類成員,在發生某些行爲時調用 |
析構函數 | 類似於構造函數的語法 |
類型 | 類可以包含內部類 |
1.字段
字段時與類相關的變量。
實例化示例1的對象之後,就可以用如下方法訪問:
var customer1 = new PhoneCustomer();
Console.WriteLine(customer1.CustomerID);
使用const聲明常量,如果將其聲明爲public,就可以在類外訪問它。
最好不要把字段聲明爲public。
2.屬性
**概念:**他是一個方法或一對方法,在客戶端代碼看來,他們是一個字段。
例如:
class PhoneCustomer
{
private string _firstName;
public string FirstName
{
get { return _firstName; }
set { _firstName = value; }
}
}
包括get和set兩個訪問器,用來獲取和設置字段的值
a、自動實現的屬性
如果屬性的set和get訪問器中沒有任何的邏輯,就可以使用自動實現的屬性。這種書行賄自動實現後被成員變量。
例如:
public int Age { get; set; }
不需要聲明私有字段。編譯器就會自動創建它。自動實現的屬性可以使用屬性初始化器來初始化
public int Age { get; set; } = 42;
b、屬性的訪問修飾符
C#允許給屬性的get和set訪問器設置不同的訪問修飾符,所以可以有共有的get訪問器和私有的set訪問器。有卒於控制屬性的設置方式和時間;在get和set訪問器中,必須有一個具備屬性的訪問級別;
例如:
public string FirstName
{
get { return _firstName; }
private set { _firstName = value; }
}
public int Age { get;private set; } = 42;
3.方法
a、方法的聲明
形式:
修飾符 返回值類型 方法名(參數列表)
{
方法體
}
例如:
private string getName(string id)
{
return Name;
}
b、 表達式體方法
如果方法的實現只有一條語句,C#6提供一個簡化方法:表達式體方法
捨棄了花括號和return關鍵字,使用=>區分左邊聲明和右邊實現代碼
例如:private string getName(string id)=>Name;
c、調用方法
實例:
using System;
using System.Threading;
namespace ConsoleApp2
{
class Math
{
public int value{get; set;}
public int getSquare() => value * value;
public static int getSquareOf(int x) => x * x;
public static double GetPi() => 3.14159;
static void Main(string[] args)
{
Console.WriteLine("Pi is "+Math.GetPi());
Console.WriteLine($"Pi is {Math.getSquareOf(5)}");
var math = new Math();//實例化一個對象
math.value = 30;
Console.WriteLine($"value field of math variable contains{math.value}");
Console.WriteLine($"square if 30 is {math.getSquare()}");
Thread.Sleep(5000);//睡眠5000毫秒,也就是5秒
}
}
}
結果:
理解上述實例就能輕鬆掌握調通方法的技巧。
d、方法的重載
定義:方法名相同,但方法的參數個數和數據類型不同。
(上述例子只爲重載而重載,沒有任何實際意義)
e、可選參數
假如一個方法有兩個參數,其中有一個參數調用時可能會用到,也可能時默認值。這時候我們就可以將其設置爲可選參數。例:
public static int getSquareOf(int x,int y = 42) => x * x * y * y;
我們調用的方法有下列兩種;
Math.getSquareOf(5);
或
Math.getSquareOf(5,1);
注意:可選參數可以有有多個,可選參數必須放在參數的最後面。
例如:
public static void getSquareOf(int x, int y = 5, int z = 4)
{
Console.WriteLine($"x is {x}");
Console.WriteLine($"y is {y}");
Console.WriteLine($"z is {z}");
}
調用示範:
Math.getSquareOf(1,z:3);
Math.getSquareOf(1,y:2);
f、個數可變參數
除了可選參數外,還有一種方法可以實現參數個數可變的方法;
實例:(注意getSquareOf方法)
using System;
using System.Threading;
namespace ConsoleApp2
{
class Math
{
public int value{get; set;}
public int getSquare() => value * value;
public static void getSquareOf(params int[] x)
{
foreach (int temp in x)
{
Console.Write(temp+" ");
}
Console.WriteLine();//換行
}
public static double GetPi() => 3.14159;
static void Main(string[] args)
{
Math.getSquareOf(1);
Math.getSquareOf(1,2,3,4);
Math.getSquareOf(1,2,3,4,5,6,7,8,9,10);
Thread.Sleep(5000);//睡眠5000毫秒,也就是5秒
}
}
}
結果:
如果想將不同類型的參數傳給方法,可以將int數組換成obiect數組。如果params關鍵字與其他參數一起使用,需要將其放在最後,並只能使用一次。
4.構造方法
構造函數名必須與類名相同,但是沒有返回值。
例如:
class Math
{
public Math()
{
}
}
如果開發者沒有給類提供構造函數,那麼編譯器就會生成一個極其簡單的構造函數用來初始化工作。
a、在構造函數中調用其它構造函數
有類如下👇
class Math
{
int x;
int y;
public Math(int _x)
{
x = _x;
y = 2;
}
public Math(int _x,int _y)
{
x = _x;
y = _y;
}
//etc
咋一看這個代碼,有兩個構造函數,函數體大致相同,只有y變量操作不同,如果操作再多一點,就會造成代碼重複,啥玩應 。那麼,他來了!!!!!!(構造函數初始化器)
👏👏👏
class Math
{
int x;
int y;
public Math(int _x):this( _x, 2)
{
}
public Math(int _x,int _y)
{
x = _x;
y = _y;
}
//etc
是不是感覺變好看了呢!this關鍵字只調用參數最匹配的那個構造函數
C#構造函數初始化器可以包含對同一個類的構造函數的調用(上述語法),也可以對積累的構造函數進行調用(使用相同的語法,但應該將this換成base),初始化器不能有多個調用
b、靜態構造函數
可以編寫無參的靜態構造函數是C#的特徵之一。這種構造函數只執行一次,通常在第一次實用類之前執行。。
“同學A:爲啥要寫靜態構造函數?”
“老師:不知道”
“老師:”類有一些靜態字段或屬性,需要在使用前進行初始化。
注意:靜態構造函數沒有訪問修飾符,其他C#代碼從不顯示調用它,.NET運行庫在加載類是調用它,且只能訪問類的靜態成員
使用範例:
using System;
using System.Drawing;
using System.Threading;
namespace ConsoleApp2
{
public static class UserPreferences
{
public static Color BackColor { get; }
static UserPreferences()
{
DateTime now = DateTime.Now;
if (now.DayOfWeek == DayOfWeek.Saturday || now.DayOfWeek == DayOfWeek.Sunday)
{
BackColor = Color.Green;
}
else
{
BackColor = Color.Red;
}
}
static void Main(string[] args)
{
Console.WriteLine($"User-preferences:BackColor is : {UserPreferences.BackColor}");
Thread.Sleep(5000);//睡眠5000毫秒,也就是5秒
}
}
}
如果理解了上述代碼,那麼恭喜你這節畢業了。👏👏👏👏
5.只讀字段
只讀字段用readonly修飾符聲明,只能在構造函數中分配值。與const不同,編譯器通過const,用他的值取代變量。與const相反,只讀字段可以作爲實例成員,這是需要加上static。
比如說一個文檔編輯程序,需要限制文檔最大打開數。現在顧客升級該程序後需要修改文檔最大打開數。顯然不能再源代碼中對其進行硬編碼,而是需要一個只讀字段來表示,每次打開程序時讀取。
public static class UserPreferences
{
private static readonly uint max_Count;
static UserPreferences()
{
max_Count = DoSometh();
}
//etc
只讀屬性
在屬性定義中省略set訪問器就可以創建只讀屬性。
用readonly修飾符聲明字段只允許在構造函數中初始化屬性的值。
6.匿名類型
var關鍵字用於表示隱式類型化的變量,new和var關鍵字一起使用時可以創建匿名類型,匿名類型是一個繼承自object且沒有名稱的類。該類的定義從初始化器中推斷,類似於隱式類型化的變量。
var caption = new
{
firstName = "James",
middleName = "T",
lastName = "Kirk"
};
在寫另一個匿名類型
var doctor = new
{
firstName = "w",
middleName = "j",
lastName = "s"
};
那麼就可以說doctor和caption類型相同,當類型相同時,可以設置caption = doctor。
當設置的值來自於一個有存在對象可以這樣寫:
var doctor = new
{
caption.firstName,
caption.middleName,
caption.lastName
};
7.枚舉
枚舉時一個值類型,包含一組命名的常量。示例如下:👇
public enum color
{
red,
green,
blue
}
可以聲明枚舉類型變量:
color c1 = color.red;
默認情況下,enum的類型是int。可以改爲其他整數類型(byte,short、int、帶符號的long和無符號的變量)。命名常量的值從0開始遞增。也可以改爲其他值
public enum color:short
{
red = 1,
green = 2,
blue = 3
}
使用強制類型轉換可以把數字轉換爲枚舉值,或者把枚舉值轉換爲數字。
color c2 = (color)2;
short = number = (short)c2;
8.部分類
partial關鍵字允許把類、結構、方法或接口放在多個文件中。簡單的說就是把類、結構、方法或接口拆開放在不同的源文件下。
partial用法:將其放在class、struct或interface關鍵字前面。
部分類可以包含部分方法
例如:
public void MethodOne()
{
ApartialMethod();
}
public partial void ApartialMethod()
{
}
9.擴展方法
擴展方法是給對象添加功能的一個選項,在不能使用繼承時,可以使用。
例如:(擴展string)
public static int GetCountOfWord(this string s) => s.Split().Length;
使用this關鍵字和第一個參數來擴展字符串,這個關鍵字定義了要擴展的類型
10.Object類
Tpstring()方法: 轉換爲字符串。
GetHashCode()方法: 如果對象放在名爲映射(散列表或字典)的結構中,就可以使用這個方法。
GetType方法: 返回一個從System.Object派生的類的一個實例。
MemberwiseClone方法: 複製對象並返回一個對副本的引用。