- 環境:VS和VC的區別與聯繫
VS 是 Visual Studio,它是微軟提供的一個工具集,由各種各樣的工具組成。VS 可以支持 C/C++、VB、JAVA、C# 編程。然了一次只能支持一種編程方式。在 VS 安裝完成,第一次運行的時候會讓你選擇常用語言,如果你選擇 C/C++,那麼他就成了能夠進行 C/C++ 編程的平臺也許就是你所說的 VC 了。如果不想用 C/C++ 的話,只需要修改一下他的初始化設置,選擇別的編程語言,就成爲了另一種的語言的編程環境了。
VC 是 Visual C++,是一個獨立的 C/C++ 的開發工具,比較著名的是 VC6.0,現在的 VC2010其實就是 VC10.0。
再通俗一點,以 VS2010 和 VC2010 爲例,VS2010 相當與 Office2010,包括了 World2010、Excel2010 等,而 VC2010 就相當於是 World2010。
- 數據類型:字符串(String)類型
這裏的 String 和之前學過的C語言有一點點區別,它允許給變量分配任何字符串值。字符串(String)類型是 System.String 類的別名。它是從對象(Object)類型派生的。字符串(String)類型的值可以通過兩種形式進行分配:引號和 @引號。
例如:
String str = "runoob.com";
一個 @引號字符串:
@"runoob.com";
C# string 字符串的前面可以加 @(稱作"逐字字符串")將轉義字符(\)當作普通字符對待,比如:
string str = @"C:\Windows";
等價於:
string str = @"C:\Windows";
@ 字符串中可以任意換行,換行符及縮進空格都計算在字符串長度之內。
string str = @"<script type=""text/javascript"">
<!--
-->
</script>";
tring 是 C# 中的類,String 是 .net Framework 的類(在 C# IDE 中不會顯示藍色) C# string 映射爲 .net Framework 的String 如果用 string, 編譯器會把它編譯成 String,所以如果直接用 String 就可以讓編譯器少做一點點工作。
如果使用 C#,建議使用 string,比較符合規範 string 始終代表 System.String(1.x) 或 ::System.String(2.0) ,String 只有在前面有 using System;的時候並且當前命名空間中沒有名爲 String 的類型(class、struct、delegate、enum)的時候才代表 System.String string 是關鍵字,String 不是,也就是說 string 不能作爲類、結構、枚舉、字段、變量、方法、屬性的名稱,而 String 可以。
String 是 CLR 的類型名稱(也算是關鍵字),而 string 是 C# 中的關鍵字。string 在編譯時候 C# 編譯器會默認將其轉換爲 String,在這裏會多增加幾行轉換的代碼。很多時候都是建議使用 CLR 的類型而不要使用 C# 的類型(這是專家的建議)。比如說還有:使用 int 的時候最好使用 Int32 等。很多時候都是一個習慣問題,規範問題。還有一個不同就是在 VS 中表現的顏色不一樣:String 是綠色,string 是藍色。
- 顯示轉換:as和強制類型轉換的區別
強制類型轉換:轉換不成功會拋出異常,對引用類型和值類型都適用。
as運算符:轉換不成功得到一個null值,不會拋出異常;僅適用於引用類型,不能用於值類型。
沒搞清楚 Convert.ToInt32 和 int.Parse() 的細細微區別時千萬別亂用,否則可能會產生無法預料的結果,舉例來說:假如從 url 中取一個參數 page 的值,我們知道這個值是一個 int,所以即可以用 Convert.ToInt32(Request.QueryString["page"]),也可以用 int.Parse(Request.QueryString["page"]),但是如果 page 這個參數在 url 中不存在,那麼前者將返回 0,0 可能是一個有效的值,所以你不知道 url 中原來根本就沒有這個參數而繼續進行下一下的處理,這就可能產生意想不到的效果,而用後一種辦法的話沒有 page 這個參數會拋出異常,我們可以捕獲異常然後再做相應的處理,比如提示用戶缺少參數,而不是把參數值當做 0 來處理。
(1) 這兩個方法的最大不同是它們對 null 值的處理方法: Convert.ToInt32(null) 會返回 0 而不會產生任何異常,但 int.Parse(null) 則會產生異常。
(2) 對數據進行四捨五入時候的區別
a. Convert.ToInt32(double value) 如果 value 爲兩個整數中間的數字,則返回二者中的偶數;即 3.5 轉換爲 4,4.5 轉換爲 4,而 5.5 轉換爲 6。不過 4.6 可以轉換爲 5,4.4 轉換爲 4 。
b. int.Parse("4.5") 直接報錯:"輸入字符串的格式不正確"。
c. int(4.6) = 4 Int 轉化其他數值類型爲 Int 時沒有四捨五入,強制轉換。
(3) 對被轉換類型的區別 int.Parse 是轉換 String 爲 int, Convert.ToInt32 是轉換繼承自 Object 的對象爲 int 的(可以有很多其它類型的數據)。你得到一個 object 對象, 你想把它轉換爲 int, 用 int.Parse 就不可以, 要用 Convert.ToInt32。
C# 可空類型(Nullable)
C# 提供了一個特殊的數據類型,nullable 類型(可空類型),可空類型可以表示其基礎值類型正常範圍內的值,再加上一個 null 值。
例如,Nullable< Int32 >,讀作"可空的 Int32",可以被賦值爲 -2,147,483,648 到 2,147,483,647 之間的任意值,也可以被賦值爲 null 值。類似的,Nullable< bool > 變量可以被賦值爲 true 或 false 或 null。
在處理數據庫和其他包含可能未賦值的元素的數據類型時,將 null 賦值給數值類型或布爾型的功能特別有用。例如,數據庫中的布爾型字段可以存儲值 true 或 false,或者,該字段也可以未定義。
聲明一個 nullable 類型(可空類型)的語法如下:
< data_type> ? <variable_name> = null;
using System;
namespace CalculatorApplication
{
class NullablesAtShow
{
static void Main(string[] args)
{
int? num1 = null;
int? num2 = 45;
double? num3 = new double?();
double? num4 = 3.14157;
bool? boolval = new bool?();
// 顯示值
Console.WriteLine("顯示可空類型的值: {0}, {1}, {2}, {3}",
num1, num2, num3, num4);
Console.WriteLine("一個可空的布爾值: {0}", boolval);
Console.ReadLine();
}
}
}
//輸出結果
//顯示可空類型的值: , 45, , 3.14157
//一個可空的布爾值:
Null 合併運算符( ?? )
Null 合併運算符用於定義可空類型和引用類型的默認值。Null 合併運算符爲類型轉換定義了一個預設值,以防可空類型的值爲 Null。Null 合併運算符把操作數類型隱式轉換爲另一個可空(或不可空)的值類型的操作數的類型。
如果第一個操作數的值爲 null,則運算符返回第二個操作數的值,否則返回第一個操作數的值。
using System;
namespace CalculatorApplication
{
class NullablesAtShow
{
static void Main(string[] args)
{
double? num1 = null;
double? num2 = 3.14157;
double num3;
num3 = num1 ?? 5.34; // num1 如果爲空值則返回 5.34
Console.WriteLine("num3 的值: {0}", num3);
num3 = num2 ?? 5.34;
Console.WriteLine("num3 的值: {0}", num3);
Console.ReadLine();
}
}
}
//運行結果
//num3 的值: 5.34
//num3 的值: 3.14157
1、結構是值類型,它在棧中分配空間;而類是引用類型,它在堆中分配空間,棧中保存的只是引用。
2、結構類型直接存儲成員數據,讓其他類的數據位於堆中,位於棧中的變量保存的是指向堆中數據對象的引用。
依賴倒置原則
依賴倒置原則,DIP,Dependency Inverse Principle DIP的表述是:
1、高層模塊不應該依賴於低層模塊, 二者都應該依賴於抽象。
2、抽象不應該依賴於細節,細節應該依賴於抽象。
這裏說的“依賴”是使用的意思,如果你調用了一個類的一個方法,就是依賴這個類,如果你直接調用這個類的方法,就是依賴細節,細節就是具體的類,但如果你調用的是它父類或者接口的方法,就是依賴抽象, 所以 DIP 說白了就是不要直接使用具體的子類,而是用它的父類的引用去調用子類的方法,這樣就是依賴於抽象,不依賴具體。
其實簡單的說,DIP 的好處就是解除耦合,用了 DIP 之後,調用者就不知道被調用的代碼是什麼,因爲調用者拿到的是父類的引用,它不知道具體指向哪個子類的實例,更不知道要調用的方法具體是什麼,所以,被調用代碼被偷偷換成另一個子類之後,調用者不需要做任何修改, 這就是解耦了。
多態:一個接口多個功能。
靜態多態性:編譯時發生函數響應(調用);
動態多態性:運行時發生函數響應。
靜態綁定(早期綁定):編譯時函數和對象的連接機制。 兩種技術實現靜態多態性:函數重載/運算符重載。
函數重載:在同一範圍內對相同函數名有多個定義,可以是參數類型或參數個數的不同,但不許只有返回值類型不同。
運算符重載:
關鍵字 abstract 聲明抽象類:用於接口部分類的實現(派生類繼承抽象類時,實現完成)。抽象類包含抽象方法,抽象方法可被派生類實現。
抽象類規則:
1.不能創建抽象類的實例
2.不能在抽象類外定義抽象方法
3.不能把抽象類聲明爲sealed(類前帶關鍵字sealed代表該類是密封類,不能被繼承)
關鍵字virtual聲明虛方法:用於方法在繼承類中的實現(在不同的繼承類中有不同的實現)。
抽象類和虛方法共同實現動態多態性。
注:繼承類中的重寫虛函數需要聲明關鍵字 override,在方法參數傳入中寫(類名 形參名)例如 public void CallArea(Shape sh),意思是傳入一個 shape 類型的類。
using的用法:
1. using指令:引入命名空間
這是最常見的用法,例如:
using System;
using Namespace1.SubNameSpace;
2. using static 指令:指定無需指定類型名稱即可訪問其靜態成員的類型
using static System.Math;var = PI; // 直接使用System.Math.PI
3. 起別名
using Project = PC.MyCompany.Project;
4. using語句:將實例與代碼綁定
using (Font font3 = new Font("Arial", 10.0f),
font4 = new Font("Arial", 10.0f))
{
// Use font3 and font4.
}
代碼段結束時,自動調用font3和font4的Dispose方法,釋放實例。
參考資料: