C#是微軟團隊在開發.NET框架時開發的,它的構想接近於C、C++,也和JAVA十分相似,有許多強大的編程功能。
個人感受是C#吸收了眾多編程語言的優點,從中可以看到C、C++、Java、Javascript、python的影子,設計思想都是相通的(過段時間一定要看看設計模式),對比遷移地學習基本只需要記關鍵字、語法和包的用法。我是為了unity游戲開發課程學的,不是很深入,某些細節可能也沒有涉及到。 就先復習了以前學C++、java的筆記,然后對照着簡單學了C#,會重點學unity中用到的包。
1.C#程序結構
C# 中的關鍵組織結構概念包括程序、命名空間、類型、成員和程序集。
一個C#版HelloWorld直觀感受一下。
using System; //包含命名空間
namespace HelloWorldApplication //聲明一個命名空間
{
class HelloWorld //類聲明
{
static void Main(string[] args) //Main入口函數
{
/* 我的第一個 C# 程序*/
Console.WriteLine("Hello World"); //輸出
Console.ReadKey();
}
}
}
與 Java 不同,文件名可以不同於類的名稱。
2.數據類型、類型轉換
- 值類型 (從System.ValueType中派生)
bool、byte、char、decimal、double、float、int、long、sbyte、short、uint、ulong、ushort、結構體struct、枚舉enum - 引用類型
引用類型不包含存儲在變量中的實際數據,而是包含對變量的引用。
內置的引用類型有:object、dynamic 和 string。
自定義的有:類class C {...}
、接口interface I {...}
、委托delegate int D(...)
、數組int[]
和int[,]
。
對象類型變量的類型檢查是在編譯時發生。
動態類型變量的類型檢查是在運行時發生。
@引號的字符串會將轉義字符(\)當作普通字符,可以任意換行,換行符及縮進空格都計算在字符串長度之內。
字符串的占位符為{},如:String.Format(“{0},{1}”,c,d);
- 指針類型
指針類型變量存儲另一種類型的內存地址。
例如:char* cptr;
- 可空類型
null是引用類型變量的默認值,null不允許被賦給值類型的變量,但有時我們希望值類型的數據可以為null,就有了可空類型。
合並運算符(??)定義了一個預設值,以防可空類型的值為null。int a = null; // 非法 int? a = null; // 合法,可空類型 Nullable<int> i = new Nullable<int>(3);//可空類型
如:double? num1 = null; double num3 = num1 ?? 5.34; // num1 如果為空值則返回 5.34
類型轉換如:i = (int)d;i.ToString();s.ToBoolean();
C#的運算符,判斷、循環語句和C++的語法基本一致,不做過多說明。
3.方法、類、接口、泛型
一個 訪問修飾符 定義了一個類成員的范圍和可見性。
C# 支持的訪問修飾符如下所示:
public:所有對象都可以訪問;
private:對象本身在對象內部可以訪問;
protected:只有該類對象及其子類對象可以訪問
internal:同一個程序集的對象可以訪問;
protected internal:訪問限於當前程序集或派生自包含類的類型。
C# 中定義方法:
<Access Specifier> <Return Type> <Method Name>(Parameter List)
{
Method Body
}
C#中的類和java是很像的,不過繼承的時候用的:,而不是extends。
類中也有構造函數、析構函數、靜態成員(static)。
class Line
{
private double length; // 線條的長度
public Line() // 構造函數
{
Console.WriteLine("對象已創建");
}
~Line() //析構函數
{
Console.WriteLine("對象已刪除");
}
public void setLength( double len )
{
length = len;
}
}
類的繼承:
class <派生類> : <基類1>,<基類2>,...
{
...
}
接口的繼承和實現也是用的冒號:
interface IMyInterface : IParentInterface
{
}
class InterfaceImplementer : IMyInterface
{
//接口中方法的實現
}
泛型:
using System.Collections.Generic;
GenericList<float> list1 = new GenericList<float>();
C#的泛型和C++模板類似,但也有不同
泛型可以通過使用 where 上下文關鍵字指定約束。
4.域(Field)、屬性(Peoperty)、索引器(Indexer)
域和屬性的區別
區別 | 屬性 | 域 |
---|---|---|
邏輯性 | 邏輯字段,在改變字段時 能改變對象的其他一些狀態 |
不經過邏輯處理 |
存儲性 | 不占用實際內存 | 占內存空間及位置 |
訪問性 | 由get、set訪問器決定讀寫屬性 | 由訪問修飾符決定 |
安全性 | 增加了數據的安全性 | 不太安全 |
為了實現對字段的封裝,保證字段的安全性,而產生了屬性,其本質是方法,通常是配合使用的,如下:
class Student
{
private string name = "not known";
// 聲明類型為 string 的 Name 屬性
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
}
索引器
索引器(Indexer)允許一個對象可以像數組一樣被索引。
和屬性類似,可使用 get 和 set 訪問器來定義索引器,而索引器返回或設置對象實例的一個特定值。
5.委托、匿名函數、事件
委托
委托可以理解為函數指針,是對函數原型的包裝。
但相比於函數指針,委托面向對象,類型更安全,有多播的功能。
通過委托,可以將方法視為可分配給變量並可作為參數傳遞的實體。
例如:
- 申明委托:
delegate void TestDelegate(string s);
可以再任何地方聲明委托,可以帶訪問修飾符。
委托不關心引用的方法的類,只關心引用的方法是否與委托有相同的參數和返回類型。 - 實例化委托:
TestDelegate testdelA = new TestDelegate(M);
用某個方法實例化這個委托,也就是說,使函數指針指向一個方法。 - 調用委托:
testdelA("Hello");
- 委托可以多播
委托間可以使用+、-來組合、移除,委托判等是根據它引用的方法判斷。 - 泛型委托:
delegate T NumberChanger<T>(T n);
匿名函數與Lambda表達式
匿名方法(Anonymous methods) 提供了一種傳遞代碼塊作為委托參數的技術。
匿名方法沒有名稱只有主體,不需要指定返回類型,它是從方法主體內的 return 語句推斷的。
匿名函數與委托的使用步驟相同,實例化時格式不同,格式如下:
委托名 實例變量 =delegate(形參列表){方法體};
Lambda表達式也是匿名函數,語法更加簡潔:
(參數列表) => {方法體}
事件
事件使用 發布-訂閱(publisher-subscriber) 模型。
在類的內部聲明事件,首先必須聲明該事件的委托類型。例如:
public delegate void BoilerLogHandler(string status);
然后,使用 event 關鍵字聲明事件本身:
public event BoilerLogHandler BoilerEventLog;
6.C#常用類庫
System.Collections
集合(Collection)類是專門用於數據存儲和檢索的類。常用的有:
集合類 | 常用方法 |
動態數組 ArrayList |
Add(item)、Clear()、Contains()、IndexOf()、 Remove()、Sort()、Reverse() |
哈希表 Hashtable |
Add(key,value)、Clear()、Remove(key)、 ContainsKey(key)、ContainsValue(value) |
堆棧 Stack |
Clear()、Contains()、Peek()、 Pop()、PushToArray() |
隊列 Queue |
Clear()、Contains()、Dequeue()、 Enqueue()、ToArray()、TrimToSize() |
點陣列 BitArray |
|
排序列表 SortedList |
|