日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

写好C#代码的技巧

發布時間:2023/12/4 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 写好C#代码的技巧 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

寫好C#代碼的技巧

編者導語

本文來自https://www.pluralsight.com,作者Afzaal Ahmad Zeeshan。

原文包含以下三篇文章:

《編寫更好的C#代碼簡介》https://www.pluralsight.com/guides/introduction-to-writing-better-csharp-code

《編寫更好的C#代碼的技巧》https://www.pluralsight.com/guides/tips-for-writing-better-c-code

《有關編寫更好的C#代碼的更多技巧》https://www.pluralsight.com/guides/more-tips-for-writing-better-csharp-code

雖然本文僅介紹了C#6.0語言特性,而現在最新的C#已經到了9.0,但這些內容已經仍然常讀常新。

一、簡介

C#已從C#5更改為C#6,為使項目更具可讀性,基于最佳標準的實踐也得到了發展。

本指南系列的目的是幫助您為在團隊環境中運行的C#項目和.NET Framework應用程序編寫更簡潔的代碼。在團隊環境下,編寫好的代碼對開發人員可能更容易,因為編寫的代碼將由團隊中其他開發人員使用,管理和更新,而代碼質量往往取決于您個人團隊的“哲學”和開發人員的編碼實踐。

在這種情況下,最好的方法是遵循編碼團隊的準則,并為應用程序項目中的C#程序添加設計和風格,以使它們對讀者更好。請注意,C#編譯器并不關心您放入代碼中的風格。但我們以一種使C#應用程序對讀者來說看起來更簡單,更清潔,將更容易的方式更深入地進行編程,同時保持代碼開發的性能和效率。

在閱讀本指南之前,您應該了解以下幾點:

1.第6版對C#的改進2..NET框架中的LINQ3.TaskC#中的異步編程和對象4.使用C#進行的不安全編程,使您無法正常的使用內存管理

不專注于性能

應該注意的是,我不會談論改變程序性能,提高效率或減少程序運行所花費的時間。通過編寫簡潔的C#代碼,您可以在幾秒鐘內提高程序性能,但是以下技巧并不能保證您的代碼性能更好。

為什么要編寫整潔的代碼?

您編寫代碼,編譯器編譯時沒有警告也沒有錯誤,代碼很好。但是,如果其他人想讀出該代碼怎么辦?如果有人后來需要為您或您所在的公司升級代碼,該怎么辦?看下面的代碼:

public static void Main(string[] args) {int x = 0;x = Console.Read();Console.WriteLine(x * 1.5); }

該程序運行良好,系統中沒有錯誤,應用程序也可以正常工作。但是您能告訴我該程序在現實生活中做什么嗎?以下是可以做出的一些假設:

1.它只是乘以價值2.就像獎金一樣,它正在增加價值3.是個人銀行存款總額的利率4.等等。

哪一個是真實的?沒有人會知道。在這種情況下,最好編寫出良好的代碼,并記住遵循編程的基礎??聪旅娴拇a:

public static void Main(string[] args) {int salary = 0;salary = Console.Read();Console.WriteLine(salary * 1.5); }

這比以前的代碼有意義嗎?我們可以很容易地說這個代碼將增加薪水的價值。請注意,僅通過改進代碼,我們就能確保其他人可以比以前更快地理解它。

在本指南中,我不會向您展示如何遵循最佳原則。相反,我將以您已有的知識為基礎,并教您如何充分利用C#程序。我將重點介紹如何在應用程序中編寫良好的C#邏輯,因此您將看到通過以這種方式和結構編寫程序,可以從應用程序中獲得很多好處。

因此,讓我們開始吧。

對象初始化

C#是一種面向對象的編程語言。如果對象本身沒有分塊,那么寫一組提示有什么好處?本節將重點介紹在前進并new Object()在應用程序中編寫代碼之前應考慮的事項。您必須了解如何創建C#類以及事物如何協作以在系統中啟動一個小程序。

例如,看下面的代碼:

class Person {public int ID { get; set; }public string Name { get; set; }public DateTime DateOfBirth { get; set; }public bool Gender { get; set; } }

您可能想要創建默認情況下設置值的程序,或者讓它們來自模型或諸如此源代碼的任何其他面向數據庫的數據源,這些程序簡化了在對象時輸入默認值的方式正在創建。

var person = new Person { ID = 1, Name = "Afzaal Ahmad Zeeshan", DateOfBirth = new DateTime(1995, 08, 29), Gender = true };

相反,請嘗試通過以下方式編寫相同的代碼:

var person = new Person(); person.ID = 1; person.Name = "Afzaal Ahmad Zeeshan"; // So on.

這里的代碼沒有明顯的性能改進,但是可以真正提高代碼的可讀性。如果您喜歡縮進,請在這里查看:

var person = new Person {ID = 1,Name = "Afzaal Ahmad Zeeshan",DateOfBirth = new DateTime(1995, 08, 29),Gender = true };

這也有縮進,但是它為您的C#代碼的可讀性添加了更多的說明。盡管前面的代碼可以實現相同的功能,但是建議的代碼可以使代碼更易讀和簡潔。

二、技巧

空檢查

NullReferenceException當缺少初始化的對象再次拋出異常時,您是否曾經對感到惱火?在程序中進行空檢查有很多好處,不僅可以提高可讀性,而且可以確保程序不會由于內存問題而終止(例如,內存中不存在變量時)。這些可能與程序的安全性以及團隊具有的良好UI和UX準則相抵觸。大多數情況下,由于以下原因會引發空異常:

string name = null;Console.WriteLine(name);

在大多數情況下,除非您解決此問題,否則編譯器本身不會繼續運行,但是如果您設法以某種方式誘使編譯器認為變量具有值,但在運行時沒有變量,則會出現空引用異常。為了克服這個問題,您可以執行以下操作:

string name = null;// Try to enter the value, from somewhere if(name != null) {Console.WriteLine(name); }

此安全檢查將確保在調用此變量時該值可用。否則,它將影響您代碼的路徑。但是,在C#6中,還有另一種方法可以克服此錯誤。考慮以下情形:建立數據庫,建立數據表,找到您的人員但找不到他們的就業詳細信息。你能找到他們工作的公司嗎?

var company = DbHelper.PeopleTable.Find(x => x.id == id).FirstOrDefault().EmploymentHistory.CompanyName; // Error

如果您這樣做,將會出現錯誤,因為我們只能在這些值的列表中進行簡單幾步的對象篩選。然后我們將碰到一個空值,一切都丟失了。C#6提出了一種克服這些情況的新方法,方法是在值和字段可以為null的后面使用安全的導航運算符。?.。像這樣:

var company = DbHelper?.PeopleTable?.Find(x => x.id == id)?.FirstOrDefault()?.EmploymentHistory?.CompanyName; // Works

如果前一個不為null,則此代碼僅檢查下一個值。如果先前的值為null,它將返回null并將null保存為的值company,而不是引發錯誤。將檢查留給框架本身可以很方便,但是,盡管如此,您仍然必須在最后檢查其余值是否為null。

var company = DbHelper.PeopleTable?.Find(x => x.id == id)?.FirstOrDefault()?.EmploymentHistory?.CompanyName;if(company != null) {// Final process }

但是您明白了這一點,而不是編寫代碼并檢查所有內容是否為空,而是可以執行簡單的檢查并執行程序中想要的操作和邏輯。否則,將需要try...catch包裝器或多個if...else塊來控制程序在系統中的導航方式。

異步編程模式

如果您正在使用C#5進行編程,那么您已經在使用async / await關鍵字為您的應用程序帶來改進。如果不是這種情況,那么我建議您在應用程序的源代碼中使用異步編程模式。這不僅可以提高對程序的響應速度,還可以提高應用程序的可讀性。在源代碼中具有異步模式的一些好處是:

1.代碼路徑開始變得更加有意義。如果有一個進程在后臺開始運行,那么程序員可以了解程序應該在哪里。2.應用程序掛起問題將消失。大多數與應用程序阻塞相關的問題直接來自代碼。當UI線程無法更新UI時,用戶會認為該應用程序正在掛起并且沒有響應,而事實并非如此。異步方法確實可以幫上大忙。3.基于Windows運行時的應用程序完全基于此方法。您將(并且必須是!)在您的Windows Runtime應用程序中使用這種方法來解決諸如掛起應用程序或不良的編程習慣之類的問題。

自從線程化以來,代碼執行的并行化就已經存在。異步已經成為程序和應用程序的重要組成部分,因此您更應該考慮使用它。

C#字符串構建

字符串是當今應用程序的重要組成部分,構建字符串可能會花費很多時間,并且還會導致應用程序性能下降。您可以通過多種方式在C#程序中構建字符串。以下是其中幾種方式:

string str = ""; // Setting it to null would cause additional problems.// Way 1 str = "Name: " + name + ", Age: " + age;// Way 2 str = string.Format("Name: {0}, Age: {1}", name, age);// Way 3 var builder = new StringBuilder(); builder.Append("Name: "); builder.Append(name); builder.Append(", Age: "); builder.Append(age); str = builder.ToString();

請注意,C#中的字符串是不可變的。這意味著,如果您嘗試更新它們的值,則會重新創建它們,并從內存中刪除以前的句柄。這就是為什么方式1看起來是最好的方式,但經過進一步思考,事實并非如此。最好的方法是方法3,它使您可以構建字符串而不必在內存中重新創建對象。同時,C#6引入了一種全新的方式在C#中構建字符串,該方式比您以前想象的要好得多。新的

字符串插值 運算符$為您提供了以最佳方式執行字符串構建的功能。字符串插值如下所示:

static void Main(string[] args) {// Just arbitrary variablesstring name = "";int age = 0;// Our intereststring str = $"Name: {name}, Age: {age}"; }

只需一行代碼,編譯器就會自動將其轉換為string.Format()版本。為了證明這一點,將詳細說明此C#程序已生成的字節碼,并向您展示如何自動更改語法以讀取字符串格式。

IL_0000: nop IL_0001: ldstr "" IL_0006: stloc.0 // name IL_0007: ldc.i4.0 IL_0008: stloc.1 // age IL_0009: ldstr "Name: {0}, Age: {1}" IL_000E: ldloc.0 // name IL_000F: ldloc.1 // age IL_0010: box System.Int32 IL_0015: call System.String.Format IL_001A: stloc.2 // str IL_001B: ret

可以看出,這顯示了如何將語法更改回我們已經看到的語法。有關IL_0009更多信息,請參見。當其他人正在讀取程序時,這可以使您的程序外觀更簡潔,并且如果要構建的字符串較小,則可以提高性能。如果字符串較大,請使用StringBuilder。

三、更多技巧

遍歷數據

如果不對一組數據進行循環和迭代,那么應用程序有什么用?在這種情況下,有時您將不得不查找值,查找節點,查找記錄或對集合進行任何其他遍歷。在這種情況下,您確實需要確保編寫干凈的代碼,因為這是性能和可讀性都非常重要且相互關聯的領域。

有了一些經驗,我就克服了編寫用于讀取和遍歷數據的錯誤代碼的方式。這正是LINQ應該加入的地方,LINQ允許您編寫使用最佳.NET框架為用戶和客戶提供最佳編碼體驗和最佳體驗的程序。

以前,您可能已經做過以下一些事情:

6 // A function to search for people Person FindPerson(int id) {var people = DbContext.GetPeople(); // Returns List<Person>foreach (var person in people) {if(person.ID == id) {return person;}}// No person found.return null; }// Then do this var person = FindPerson(123);

對于任何想接手您代碼的人來說,這都是一段易讀的代碼。但是,使用C#中的LINQ查詢可以使代碼更加簡單和整潔。您可以通過兩種方式執行此操作。一個有點像SQL,另一個是通過Where在集合上使用該函數并傳遞我們的要求。

// A function to search for people Person FindPerson(int id) {var people = DbContext.GetPeople(); // Returns List<Person>return (from person in peoplewhere person.ID == idselect person).ToList().FirstOrDefault(); }// Then do this var person = FindPerson(123);

該代碼看起來有點像SQL,可以增強代碼的可讀性和性能。該函數相似,但是,該Where函數的讀取效果更好,并使所有迭代都針對.NET框架本身,而.NET框架將為應用程序提供最佳性能。

現在,讓我們看看用相同的C#代碼編寫此查詢的另一種方式:

// A function to search for people Person FindPerson(int id) {var people = DbContext.GetPeople(); // Returns List<Person>return people.FirstOrDefault(x => x.ID == id); }// Then do this var person = FindPerson(123);

請注意,null如果沒有找到匹配項,則返回第一個代碼。這段代碼也做同樣的事情。唯一的第一個代碼更糟糕的是它必須對集合本身執行迭代。

該本地變量return person;將允許程序返回控件,但是如果數據位于最后一個位置會發生什么呢?此數據搜索算法的復雜度仍為O(n)。

避免unsafe上下文

在您必須親自處理內存時,C#還支持手動內存管理。C#中的不安全上下文允許您操作內存,執行指針算術,在可能無法訪問的內存位置讀取和寫入數據,等等。但是,.NET框架可以做很多事情來克服內存問題,延遲和磁盤上其他問題。這也使.NET框架完全無需實際執行任何內存管理,.NET框架將為您做到這一點。

使用不安全的上下文有很多好處,例如,當您要圍繞本機C ++庫編寫包裝器時。Emgu CV就是這樣一個示例,您將在其中編寫一些代碼來處理如何管理本機代碼,并以更簡單的方式來處理內存中的錯誤。在這種情況下,您可以:

1.使用指針管理和指針算術。您不能在此上下文之外的任何地址上執行任何操作,這是.NET規則所處的位置。2.使用內存管理來操作內存中的對象。3.使用C ++風格的編程,這正是C#設計的目的。

這幾乎沒有好處,如果您應該在應用程序中考慮這一點,請明智地考慮。

關于Unsafe純屬個人觀點

我還想指出,關于“不安全”的利弊,我所說的一切都是我個人的看法。我不經常在程序中使用unsafe上下文,因為沒有理由考慮在應用程序中使用上下文。但是,如果您的應用程序需要本機內存管理,則可以使用此上下文。

盡可能使用Lambda表達式

Lambda來自函數式編程領域,在C#中已廣泛使用,從內聯函數一直到C#6中的getter only屬性。我將展示C#中的兩種用法,它們構成的程序,不僅看起來更清爽,而且性能指標也更高。

為此,我將向您顯示該C#代碼的IL。我個人喜歡在許多領域使用lambda,尤其是當我不得不用C#編寫內聯函數時。自從可以使用此概念編寫僅用于getter的屬性以來,我一直在使用它們,并且我個人認為它比以前做同一件事的方法更好。

1.將Lambda用于內聯函數

您應該知道一些C#編程的示例,使用這種寫法的代碼很多。

例如在應用程序中進行事件處理的情況下,對于事件處理,您可以像下面這樣編寫當前函數:

// Without lamdbas myBtn.Click += Btn_Click;public void Btn_Click (object sender, EventArgs e) {// Code to handle the event }// With the help of lambdas myBtn.Click += (sender, e) =>{// Code to handle the event.}

請注意,編譯器將自動將對象映射到其類型。這在許多方面都很方便,因為它允許您用C#編寫僅與對象一起保留的內聯函數,除非您也想在其他任何地方使用它們。但是,這種處理事件的方法有一個缺點:一旦附加了事件處理程序,便無法刪除它。在C#中可以,-+。

但是由于我們沒有刪除事件的參考,因此只能使用單獨的函數。但是,如果不必刪除處理程序,則應始終考慮在程序中使用這種事件處理方式。

2.將Lambda用于僅Getter的屬性

在C#中,有一個使用屬性而不是字段的概念。您可以控制如何設置值以及如何從字段中捕獲值。將其視為Java編程語言的getter和setter方法的替代方法(或類似方法)。唯一的區別是您不必在某個地方分別編寫它們,它們直接寫在字段本身的前面。然后,C#程序編譯器將創建自己的后備字段,用于存儲值。

基本上,您必須編寫如下這樣的屬性:

public string Name { get; }

請注意,這些屬性是恒定的,設置后就無法更改。它們是在構造函數中設置的,或者(從C#6開始)在它們的前面設置。像這樣:

public string Name { get; } = "Afzaal Ahmad Zeeshan";

但是,由于我們已經知道這是一個常量字段,您不能修改它,那么為什么不創建一個簡單的常量屬性呢?事情變得有些棘手。甚至一個屬性也必須由字段來備份。在這種情況下,這將為我們解決問題:

public string Name => "Afzaal Ahmad Zeeshan";

這等效于編寫以下內容:

public string Name { get { return "Afzaal Ahmad Zeeshan"; } }

但是由于編譯期將getter字段轉換為常量字段,并且在必須調用此屬性的時候才會在程序中使用該字段,因此性能要好得多。

最后的話

本指南系列的目的是使您了解一些使程序更易于閱讀和更好執行的方法。C#編譯器本身會盡最大努力提高代碼的質量和效率,而這程序員帶來便利,同時也將使程序更好地工作。

除了上面提到的方法,還有許多其他提高可讀性的方法,其中許多方法適合公司團隊協作的形式編寫程序,因為大多數團隊往往都要求程序員遵循自己的編程方法和方式。

總結

以上是生活随笔為你收集整理的写好C#代码的技巧的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。