理解C#中的變數和資料型別
[[academy-video-youtube({"vid": "UntC0hoeGAQ", "start_time": "0", "title": "Understanding C# Variables and Data Types", "creator": "Tim Corey", "length": "28m 27s"})]]
在C#編程中,變數是儲存資料值的基礎元素。 了解如何有效地定義和使用變數對於撰寫高效且易於維護的程式碼至關重要。 變數可以是不同型別的,包括基本資料型別、常量和動態型別的變數,每一種都具有特定的用途。 此外,型別轉換、動態和var關鍵字為C#編程新增了靈活性和穩固性。
Tim Corey的《Dynamic vs Var in C#》影片中提供了這些概念的綜合概述。在本文中,我們將探討Tim所涵蓋的多個主題,包括:
- 動態 vs Var 差異
- 基本資料型別
- 變數和常數
- 動態自動型別轉換
- 開發中動態的缺點
- 為什麼以及何時使用動態
- 為什麼以及何時使用Var
通過Tim Corey的解釋了解這些概念,您將更深入地了解如何在C#中有效地管理和利用變數。
動態 vs Var 差異
在C#中,var用於隱式型別本地變數,其型別在編譯時確定,從而確保型別安全性和IntelliSense支持。 相反,dynamic允許變數繞過編譯時型別檢查,型別在運行時解析,提供了更多的靈活性,但存在運行時錯誤的風險和性能的降低。
Tim Corey解釋說dynamic通過運行時型別解析提供了靈活性,這可能導致運行時錯誤和性能問題。
基本資料型別
Tim在Visual Studio中開始了其演示,介紹了C#中的基本資料型別。 他建立了一個testDynamic,可以隨時分配新值,其資料型別可以在運行時動態改變。這通過以下程式碼進行演示:
// Declaration of a dynamic variable that can change types at runtime
dynamic testDynamic;// Declaration of a dynamic variable that can change types at runtime
dynamic testDynamic;C#提供幾種基本資料型別來處理各種資料。 整數型別包括用於32位有符號整數的byte。 對於浮點數,C#提供用於單精度32位值的decimal。 bool型別用於真或假值。 此外,string資料型別代表一個字元序列,允許儲存和操作文字。
這些資料型別是C#編程的基礎,允許有效的資料儲存和處理,Tim在進一步的例子中演示了這一點。 可以在一行中聲明並分配多個整數型別int變數,如果未明確分配初始值,則每個資料型別都有一個預設值。 常量變數保持固定值,為程式碼提供了一致性。 此外,實例變數和靜態變數也可以使用這些資料型別宣告,進而保證穩固和靈活的程式結構。
變數和常數
Tim Corey 在1:21嘗試建立一個var需要初始分配才能推斷其型別:
// This will result in a compile-time error due to lack of type inference
// var testVar;// This will result in a compile-time error due to lack of type inference
// var testVar;這將導致在testVar下方出現紅色波浪線,表示存在錯誤。 在1:55,Tim解釋說var需要在宣告時分配一個型別。 例如:
// var assignment with type inference from the initial value
var testVar = 2; // testVar is inferred to be of type int// var assignment with type inference from the initial value
var testVar = 2; // testVar is inferred to be of type intTim (2:44) 演示說,如果他稍後嘗試將一個double值分配給int:
// Attempting to change the type from int to double causes an error
// testVar = 1.1; // Error: Cannot implicitly convert type 'double' to 'int'// Attempting to change the type from int to double causes an error
// testVar = 1.1; // Error: Cannot implicitly convert type 'double' to 'int'Tim (3:17) 強調var的型別在其初始分配時已設置,以後不能更改。 如果testVar最初被分配了double值,那麼它將被推斷為double:
// Another example with dynamic typing
var testVar = 2.1; // Now testVar is a double// Another example with dynamic typing
var testVar = 2.1; // Now testVar is a double儘管Tim沒有討論常量變數,但它們在C#程式中同樣重要。 在C#中,常量是使用const關鍵字聲明的,後面跟著常量變數的資料型別和識別符,例如:
// Declaring a constant variable
const int MaxValue = 100;// Declaring a constant variable
const int MaxValue = 100;常量必須在宣告時分配值,該值在程式執行期間不可更改,為程式邏輯提供不可變的值。
動態自動型別轉換
Tim強調object來允許靈活的型別處理,但具有額外的功能。 在3:53,Tim演示了dynamic如何在運行時無縫地在不同型別之間轉換,展示了其能夠處理涉及整數和雙精度數的計算,而不需要顯式強制轉換,如其程式碼範例所示:
// Demonstrating dynamic type conversion at runtime
dynamic testDynamic = 1;
testDynamic = testDynamic + 2.1;
Console.WriteLine(testDynamic); // Outputs 3.1 as it converts the integer to a double// Demonstrating dynamic type conversion at runtime
dynamic testDynamic = 1;
testDynamic = testDynamic + 2.1;
Console.WriteLine(testDynamic); // Outputs 3.1 as it converts the integer to a double這裡,Tim (4:39) 說明testDynamic最初持有一個整數值,但在加2.1時自然而然地轉換為雙精度數,結果輸出為3.1。
儘管具有靈活性,Tim警告不要過度使用dynamic,因為頻繁的型別轉換會帶來性能成本。 他強調在5:55說,dynamic應在C#開發中謹慎使用,以避免不必要的處理器負擔以及編譯時型別檢查和IntelliSense支援的損失,這對於維護穩固且無錯誤的程式碼庫至關重要。
開發中動態的缺點
Tim Corey展示了dynamic如何在您的應用程式中導致運行時錯誤和意外行為。 他首先展示如何聲明一個動態變數並分配一個初始空字串以避免立即出錯。 然後,他嘗試調用不存在的方法dynamic的一個主要缺點:缺乏編譯時檢查。
// Demonstrating lack of compile-time checks with dynamic
dynamic testDynamic = "";
// testDynamic.sayHi(); // Runtime error: method does not exist// Demonstrating lack of compile-time checks with dynamic
dynamic testDynamic = "";
// testDynamic.sayHi(); // Runtime error: method does not exist此外,在8:38 Tim展示了動態變數如何在運行時更改型別,這可能導致意外行為。 他將一個Person物件分配給一個動態變數,然後重新分配為一個字串,並展示了這種靈活性如何導致邏輯錯誤並使除錯變得困難。
// Demonstrating the potential errors with dynamic type reassignment
dynamic testDynamic = new Person();
testDynamic = "Hi";
Console.WriteLine(testDynamic); // Works fine, but not ideal for type safety// Demonstrating the potential errors with dynamic type reassignment
dynamic testDynamic = new Person();
testDynamic = "Hi";
Console.WriteLine(testDynamic); // Works fine, but not ideal for type safetyTim還解釋了動態變數缺乏IntelliSense支援,這可能由於拼寫錯誤或錯誤的方法名稱而導致運行時錯誤。 例如,在14:05時,他調用了一個不存在的屬性名稱Person物件上找到預期的方法或屬性時失敗。
// Demonstrating a runtime error due to missing property
// testDynamic.Email = "Test@test.com"; // property not found until runtime// Demonstrating a runtime error due to missing property
// testDynamic.Email = "Test@test.com"; // property not found until runtime使用Var關鍵字的優勢
相反,var是強型別的,提供了編譯時型別檢查和IntelliSense支持。 這確保了在開發期間能夠捕獲到任何與型別相關的問題,從而使程式碼更可靠且更易於維護。 Tim Corey通過建立一個Person物件分配給它來演示這一點:
// Using var for strongly-typed assignments
var testVar = new Person();
testVar.FirstName = "Sue";
testVar.LastName = "Storm";
// The use of IntelliSense assists in reducing runtime errors
Console.WriteLine(testVar.SayHello()); // Ideally a method in Person class// Using var for strongly-typed assignments
var testVar = new Person();
testVar.FirstName = "Sue";
testVar.LastName = "Storm";
// The use of IntelliSense assists in reducing runtime errors
Console.WriteLine(testVar.SayHello()); // Ideally a method in Person class嘗試調用不存在的方法或將var變數重新分配給不同的型別都將在編譯階段被捕獲,從而防止潛在的運行時錯誤。
// Attempting to change type results in compile-time errors with var
// testVar = "Hi"; // Compile-time error// Attempting to change type results in compile-time errors with var
// testVar = "Hi"; // Compile-time error方法的返回型別
在15:05,Tim演示了您還可以從方法中返回var。 例如:
// Method returning a dynamic type
public dynamic GetMessage() {
return "This is a test";
}// Method returning a dynamic type
public dynamic GetMessage() {
return "This is a test";
}嘗試返回var會導致編譯時錯誤,因為方法簽名必須指定具體的返回型別。
為什麼以及何時使用動態
Tim闡述了dynamic在特定場景中如何變得至關重要。 他解釋說,C#本質上是一門強型別語言,這意味著每個變數都分配了一個確定的型別,並且在其生命週期內保持一致。 這與JavaScript等語言形成對比,在那裡變數可以動態更改型別。
Tim在18:14說明,雖然C#是設計用於強型別變數的,但在某些情況下,特別是當與像Python、Ruby或COM物件等外部系統或語言進行互動時,動態型別可能是有益的。 他用整合Python API的例子來強調dynamic的實際需求。 在這些情況下,擁有一個能夠適應來自外部來源的各種資料型別的靈活型別系統簡化了交互。
Tim Corey於18:44強調,儘管dynamic對於跨語言交互很有用,但由於編譯時錯誤檢查和IntelliSense支持的損失,不建議在純C#程式碼中使用。 他警告說,dynamic的靈活性以性能和型別安全為代價,使其成為常規C#編程中不太理想的選擇,強型別的變數應該被優先考慮。
為什麼以及何時使用Var關鍵字
然後,Tim討論了C#中var關鍵字的用法和理念。 他指出,使用var主要有兩大派別:一部分人喜歡專門使用它,而另一部分人則偏好顯式型別聲明。
Tim於19:43解釋說,var的擁護者認為它促進了更好的命名約定,使程式碼自我文件化。 他們相信變數名稱應該足夠描述,能傳達型別而不需要顯式聲明。
另一方面(20:46),那些更喜歡顯式型別聲明的人則認為在程式碼中直接看到實際型別可以立即清楚了解本地變數的型別,無需懸停在變數上以查看其型別。 例如:
// Explicit type declaration provides clarity
string firstName = "Tim";// Explicit type declaration provides clarity
string firstName = "Tim";這是一些人較偏好的方式,因為它消除了對變數型別的任何含糊不清。
Tim在21:15分享了他的平衡方法,表示他通常對於常見資料型別如decimal。 例如:
// Explicit type ensures there's no ambiguity between float types
double myMoney = 1.1; // This is a double
decimal myMoney = 1.1M; // This is a decimal// Explicit type ensures there's no ambiguity between float types
double myMoney = 1.1; // This is a double
decimal myMoney = 1.1M; // This is a decimalTim強調,顯式聲明型別可以確保使用正確的型別,特別是當型別可能混淆時。
然而,Tim也承認List<List<Person>>可能會很冗長:
// Declaring a complex type using var
var rounds = new List<List<Person>>();// Declaring a complex type using var
var rounds = new List<List<Person>>();他還在foreach迴圈中演示了它的實用性(23:55):
// Utilizing var in loop for cleaner code
foreach (var round in rounds) {
// Do something with each round
}// Utilizing var in loop for cleaner code
foreach (var round in rounds) {
// Do something with each round
}Tim總結說,儘管var可以減少冗長,但至關重要的是確保變數名稱清晰和具有描述性,以維持可讀性和防止混淆。
通過將var與顯式型別相平衡使用,開發人員可以撰寫清晰、可維護且高效的程式碼,適當地利用兩種方法的優勢來適應上下文。
Var作為匿名物件
Tim討論了var用於型別未明確知道或在與匿名型別工作時的情況。他通過即時建立一個匿名物件來演示,這種物件沒有預定型別。 以下是他使用的程式碼:
// Creating an anonymous object with var
var myItem = new { FirstName = "Tim", Email = "test@test.com" };// Creating an anonymous object with var
var myItem = new { FirstName = "Tim", Email = "test@test.com" };在25:30,Tim解釋說,由於此物件是匿名的,且沒有特定的型別名稱,所以聲明它的變數的唯一方法是使用var。 這種方法允許在建立和使用物件時不需要定義正式類。
為了說明這在實踐中如何運作,Tim寫道(25:52):
// Outputting properties of an anonymous object
Console.WriteLine($"Hello {myItem.FirstName}: your email is {myItem.Email}");// Outputting properties of an anonymous object
Console.WriteLine($"Hello {myItem.FirstName}: your email is {myItem.Email}");當他在26:25運行程式碼時,輸出如下:
這證明var可以處理匿名物件的屬性,儘管物件是匿名的,Visual Studio仍提供了對這些屬性的IntelliSense支持。
Tim在26:54澄清說,他更喜歡使用簡單和常見型別如string,整數和類實例的顯式型別,因為這使程式碼更清晰。 但是,他在型別較長、複雜或不明確時使用var,例如用於匿名型別或複雜的型別宣告。
結論
至此您已經清楚了解C#變數和資料型別,以及dynamic關鍵字的戰略使用。 通過遵循Tim Corey的平衡方法,您可以確保程式碼中的型別安全性和清晰度,特別是在需要與外部系統互動的特定場景中,使用var關鍵字的靈活性。
要獲得更多詳細的見解,請務必觀看Tim Corey的《Dynamic vs Var in C#》影片,並查看他的YouTube頻道以獲得更多C#學習主題。




