C#高級編程9 第17章 使用VS2013-C#特性

C#高級編程9 第17章 使用VS2013

編輯定位到

?

如果默認勾選了這項,請去掉勾選,因為勾選之后解決方案的目錄會根據當前文件選中。

?可以設置項目并行生成數

?

版本控制軟件設置

所有文本編輯器行號顯示

?

啟用編輯繼續

?收集調試信息,將影響性能

?

?Code Compare這是擴展與更新里面的插件,安裝之后才會顯示,用來比較代碼是否相同

?nuget包源配置,提供了nuget更新的數據源

?目標框架的設置影響到項目基礎框架的引用,不同目標框架的項目之間不能互相引用。

?不安全代碼和警告等級可能會影響生成

特定頁指定了項目運行的起始頁面,URL指定了端口號和虛擬目錄,必須創建虛擬目錄之后才能運行項目,調試器一般使用asp.net

?項目發布一般只需要運行所需的文件

?windows服務項目可以選擇啟用本機調試,如果出現無法寫入內存的錯誤時。

web發布

?

?

?

?

?

?

?

VS2015....VS2017...

?

C#6.0特性:

    1. NameOf表達式。曾幾何時,我們一直在hardcode各種參數異常,譬如:?
      void ThrowArgumentNullException(string firstVersionArgumentName)?
      {?
      ? threw new ArgumentNullException(“firstVersionArgumentName”, “can not be null”);?
      }?
      很悲催的是第二版說不定PM就說:“這個參數名字不合適,咱改改吧”,得益于IDE的重構功能,這個很容易,直接F2改名然后回車,簽入代碼;若干天后,測試找上門來,說你的參數名字是變了,但是異常信息沒變。好吧,原來這里的hardcode字符組,這個是不會隨著重構功能改變的!?
      再來看看新的Nameof表達式給我帶來什么,同樣的功能,代碼如下:?
      void ThrowArgumentNullException(string firstVersionArgumentName)?
      {?
      ? threw new ArgumentNullException(nameof(firstVersionArgumentName), “can not be null”);?
      }?
      在回到IDE中,再次按F2觸發重構改名,你會發現異常信息也能一起改變了。
    2. 空值判斷操作符(Null-conditional operators),又一個重量級代碼提升,直接上示例代碼:?
      public static string Tuncate(this string value, int length)?
      {?
      ? if(!string.IsNullOrEmpty(value))?
      ? {?
      ? ? return value.Substring(0, Math.Min(value.Length, length));?
      ? }?
      ? return value;?
      }?
      這只是一個很小的折影,在開發過程中我們有無數這樣的方法,無數次重復為空判斷,但是這對代碼的可讀性和業務處理沒有任何提升,反而增加了代碼復雜度,讓我們更難理解當初的設計初衷。顯然,C#6.0使用null-conditional operators來向前推進了一大步:?
      public static string Tuncate(this string value, int length)?
      {?
      ? return value?.Substring(0, Math.Min(value.Length, length));?
      }?
      是不是更加簡潔明了,而且能突出業務核心邏輯!
    3. 字符串嵌入值(string interpolation),終于可以擺脫長長的string.Format函數了,如下代碼就可以輕松改寫了:?
      var fullName = string.Format(“FirstName is {0}, LastName is {1}”, customer.FirstName, customer.LastName);?
      使用新特性之后代碼:?
      var fullName = “FirstName is \{customer.FirstName}, LastName is \{customer.LastName}”;
    4. Lambda表達式函數和僅get的屬性。對于那些只有一兩句話的函數,可以省掉一些廢話了,這個新功能可以大大節省人力:?
      public override string ToString() => “\{FirstName} \{LastName}”;?
      public override int GetHashcode() => (FirstName.GetHashcode()^8) & (LastName.GetHashcode());?
      public DateTime TimeStamp { get; } => DateTime.UtcNow;
    5. 自動屬性(auto-property)和索引初始化(Index initializers),終于可以像變量一樣給屬性賦初值了,大大提升代碼可讀性。?
      public string FirstName { get; set; } = “John”;?
      public string LastName { get; set; } = “Lennon”;?
      private Dictionary<int, string> _dicts = new Dictionary<int, string> { [3] = “third”, [8] = “eight” };?
      public string FullName { get; }?
      pubic MyClass ()??
      {?
      ? FullName = “\{FirstName} \{LastName}”;?
      }
    6. 異常過濾器(Exception filter),回想曾經的錯誤處理,為了提示不同的錯誤,我們不得不定義多個自定義異常,有了異常過濾器之后,我們可以通過給異常添加一個簡單的額外屬性就可以解決了:?
      try { … }?
      catach ( CustomException ex ) if ( CheckException(ex) )?
      { … }??
      想想這個還有一個好處,比如嚴重異常日志,在這個過濾器里我們可以最簡單的判斷,發現若果是嚴重的問題,可以直接做更早的提醒。
    7. 引用靜態類(using static),懶人必備,想想某大仙在前面定義了一個超級無敵的靜態類和輔助方法,你有超級多的地方需要用,然后你就得一遍一遍的敲這個靜態類名和方法名,萬一這個靜態類名字很長就更悲催了,拷貝吧,最后總是看著大段大段重復心里很不爽(程序員大部分都有代碼潔癖),好吧,這個應用靜態類就能很好的解決了:?
      using GrapeCity.Demo.LongLongNameStaticClass;?
      void AnotherMethod()?
      {?
      ? UtilA(…) // no LongLongNameStaticClass.UtilA(…)?
      }
    8. Await增強,終于可以把await放到catch和finally塊中了,典型的用例是像IO資源操作之類可以簡單整潔的處理關閉了:?
      Resource res = null;?
      try?
      {?
      ? res = await Resource.OpenAsync(…); //一直都可以而且一直這么做的?
      ? ...?
      }?
      catch(ResourceException ex)?
      {?
      ? await Resource.LogAsync(res, ex); //寫日志吧,不阻塞?
      }?
      finally?
      {?
      ? res?.CloseAsync(); //結合空值判斷操作符更簡潔明了?
      }

C#7.0特性

    

1. out-variables(Out變量)

以前,我們使用out變量的時候,需要在外部先申明,然后才能傳入方法,類似如下:

string ddd = ""; //先申明變量
ccc.StringOut(out ddd);
Console.WriteLine(ddd);

在c#7.0中我們可以不必申明,直接在參數傳遞的同時申明它,如下:

 StringOut(out string ddd); //傳遞的同時申明
Console.WriteLine(ddd);
Console.ReadLine();

?

2.Tuples(元組)

曾今在.NET4.0中,微軟對多個返回值給了我們一個解決方案叫元組,類似代碼如下:

 static void Main(string[] args){var data = GetFullName();Console.WriteLine(data.Item1);Console.WriteLine(data.Item2);Console.WriteLine(data.Item3);Console.ReadLine();
}
static Tuple<string, string, string> GetFullName() 
{return  new Tuple<string, string, string>("a", "b", "c");
}

上面代碼展示了一個方法,返回含有3個字符串的元組,然而當我們獲取到值,使用的時候 心已經炸了,Item1,Item2,Item3是什么鬼,雖然達到了我們的要求,但是實在不優雅

那么,在C#7.0中,微軟提供了更優雅的方案:(注意:需要通過nuget引用System.ValueTuple)如下:

        static void Main(string[] args){var data=GetFullName();Console.WriteLine(data.a); //可用命名獲取到值Console.WriteLine(data.b);Console.WriteLine(data.c);Console.ReadLine();}//方法定義為多個返回值,并命名private static (string a,string b,string c) GetFullName(){return ("a","b","c");}

解構元組,有的時候我們不想用var匿名來獲取,那么如何獲取abc呢?我們可以如下:

 static void Main(string[] args){//定義解構元組(string a, string b, string c) = GetFullName();Console.WriteLine(a);Console.WriteLine(b);Console.WriteLine(c);Console.ReadLine();}private static (string a,string b,string c) GetFullName(){return ("a","b","c");}

?

3.?Pattern Matching(匹配模式)

在C#7.0中,引入了匹配模式的玩法,先舉個老栗子.一個object類型,我們想判斷他是否為int如果是int我們就加10,然后輸出,需要如下:

object a = 1;
if (a is int) //is判斷
{int b = (int)a; //拆int d = b+10; //加10Console.WriteLine(d); //輸出
}

那么在C#7.0中,首先就是對is的一個小擴展,我們只需要這樣寫就行了,如下:

object a = 1;
if (a is int c) //這里,判斷為int后就直接賦值給c
{int d = c + 10;Console.WriteLine(d);
}

這樣是不是很方便?特別是經常用反射的同志們..

那么問題來了,挖掘機技術哪家強?!(咳咳,呸 開玩笑)

其實是,如果有多種類型需要匹配,那怎么辦?多個if else?當然沒問題,不過,微軟爸爸也提供了switch的新玩法,我們來看看,如下:

我們定義一個Add的方法,以Object作為參數,返回動態類型

        static dynamic Add(object a){dynamic data;switch (a){case int b:data=b++;break;case string c:data= c + "aaa";break;default:data = null;break;}return data;}

下面運行,傳入int類型:

object a = 1;
var data= Add(a);
Console.WriteLine(data.GetType());
Console.WriteLine(data);

輸出如圖:

我們傳入String類型的參數,代碼和輸出如下:

object a = "bbbb";
var data= Add(a);
Console.WriteLine(data.GetType());
Console.WriteLine(data);

通過如上代碼,我們就可以體會到switch的新玩法是多么的順暢和強大了.

匹配模式的Case When篩選

有的基友就要問了.既然我們可以在Switch里面匹配類型了,那我們能不能順便篩選一下值?答案當然是肯定的.

我們把上面的Switch代碼改一下,如下:

            switch (a){case int b when b < 0:data = b + 100;break;case int b:data=b++;break;case string c:data= c + "aaa";break;default:data = null;break;}

在傳入-1試試,看結果如下:

?

?

4.ref?locals and returns(局部變量和引用返回)

?

首先我們知道 ref關鍵字是將值傳遞變為引用傳遞

那么我們先來看看ref locals(ref局部變量)

列子代碼如下:

       static  void Main(string[] args){int x = 3;ref int x1 = ref x;  //注意這里,我們通過ref關鍵字 把x賦給了x1x1 = 2;Console.WriteLine($"改變后的變量 {nameof(x)} 值為: {x}");Console.ReadLine();}

這段代碼最終輸出 "2"

大家注意注釋的部分,我們通過ref關鍵字把x賦給了x1,如果是值類型的傳遞,那么對x將毫無影響 還是輸出3.

好處不言而喻,在某些特定的場合,我們可以直接用ref來引用傳遞,減少了值傳遞所需要開辟的空間.

?

接下來我們看看ref ?returns?(ref引用返回)

這個功能其實是非常有用的,我們可以把值類型當作引用類型來進行return

老規矩,我們舉個栗子,代碼如下:

很簡單的邏輯..獲取指定數組的指定下標的值

static ref int GetByIndex(int[] arr, int ix) => ref arr[ix];  //獲取指定數組的指定下標

我們編寫測試代碼如下:

            int[] arr = { 1, 2, 3, 4, 5 };ref int x = ref GetByIndex(arr, 2); //調用剛才的方法x = 99;Console.WriteLine($"數組arr[2]的值為: {arr[2]}");Console.ReadLine();

我們通過ref返回引用類型,在重新賦值, arr數組中的值,相應也改變了.

總結一下:ref關鍵字很早就存在了,但是他只能用于參數,這次C#7.0讓他不僅僅只能作為參數傳遞,還能作為本地變量和返回值了

?

5.Local Functions (局部函數)

嗯,這個就有點顛覆..大家都知道,局部變量是指:只在特定過程或函數中可以訪問的變量。

那這個局部函數,顧名思義:只在特定的函數中可以訪問的函數(媽蛋 好繞口)

使用方法如下:

?

       public static void DoSomeing(){//調用Dosmeing2int data = Dosmeing2(100, 200);Console.WriteLine(data);//定義局部函數,Dosmeing2.int Dosmeing2(int a, int b){return a + b;}}

呃,解釋下來 大概就是在DoSomeing中定義了一個DoSomeing2的方法,..在前面調用了一下.(注:值得一提的是局部函數定義在方法的任何位置,都可以在方法內被調用,不用遵循逐行解析的方式)

?

6.More expression-bodied members(更多的函數成員的表達式體)

C#6.0中,提供了對于只有一條語句的方法體可以簡寫成表達式。

如下:

        public void CreateCaCheContext() => new CaCheContext();//等價于下面的代碼public void CreateCaCheContext(){new CaCheContext();} 

但是,并不支持用于構造函數,析構函數,和屬性訪問器,那么C#7.0就支持了..代碼如下:

// 構造函數的表達式寫法
public CaCheContext(string label) => this.Label = label;// 析構函數的表達式寫法
~CaCheContext() => Console.Error.WriteLine("Finalized!");private string label;// Get/Set屬性訪問器的表達式寫法
public string Label
{get => label;set => this.label = value ?? "Default label";
}

7.throw?Expressions (異常表達式)

在C#7.0以前,我們想判斷一個字符串是否為null,如果為null則拋除異常,我們需要這么寫:

        public string IsNull(){string a = null;if (a == null){throw new Exception("異常了!");}return a;}

?

這樣,我們就很不方便,特別是在三元表達式 或者非空表達式中,都無法拋除這個異常,需要寫if語句.

那么我們在C#7.0中,可以這樣:

        public string IsNull(){string a = null;return a ?? throw new Exception("異常了!");}

?

8.Generalized async return types (通用異步返回類型)

嗯,這個,怎么說呢,其實我異步用的較少,所以對這個感覺理解不深刻,還是覺得然并卵,在某些特定的情況下應該是有用的.

我就直接翻譯官方的原文了,實例代碼也是官方的原文.

異步方法必須返回 void,Task 或 Task<T>,這次加入了新的ValueTask<T>,來防止異步運行的結果在等待時已可用的情境下,對 Task<T> 進行分配。對于許多示例中設計緩沖的異步場景,這可以大大減少分配的數量并顯著地提升性能。

官方的實例展示的主要是意思是:一個數據,在已經緩存的情況下,可以使用ValueTask來返回異步或者同步2種方案

    public class CaCheContext{public ValueTask<int> CachedFunc(){return (cache) ? new ValueTask<int>(cacheResult) : new ValueTask<int>(loadCache());}private bool cache = false;private int cacheResult;private async Task<int> loadCache(){// simulate async work:await Task.Delay(5000);cache = true;cacheResult = 100;return cacheResult;}}

調用的代碼和結果如下:

        //main方法可不能用async修飾,所以用了委托.static  void Main(string[] args){Action act = async () =>{CaCheContext cc = new CaCheContext();int data = await cc.CachedFunc();Console.WriteLine(data);int data2 = await cc.CachedFunc();Console.WriteLine(data2);};// 調用委托  act();Console.Read();}

上面的代碼,我們連續調用了2次,第一次,等待了5秒出現結果.第二次則沒有等待直接出現結果和預期的效果一致.

?

9.Numeric literal syntax improvements(數值文字語法改進)

這個就純粹的是..為了好看了.

在C#7.0中,允許數字中出現"_"這個分割符號.來提高可讀性,舉例如下:

            int a = 123_456;int b = 0xAB_CD_EF;int c = 123456;int d = 0xABCDEF;Console.WriteLine(a==c);Console.WriteLine(b==d);//如上代碼會顯示兩個true,在數字中用"_"分隔符不會影響結果,只是為了提高可讀性

當然,既然是數字類型的分隔符,那么?decimal,?float?和?double??都是可以這樣被分割的..

轉載于:https://www.cnblogs.com/licin/p/7235007.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/281256.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/281256.shtml
英文地址,請注明出處:http://en.pswp.cn/news/281256.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

還在手畫C#依賴關系圖嗎?快來試試這個工具吧!

還在手畫C#依賴關系圖嗎&#xff1f;快來試試這個工具吧&#xff01;筆者最近見到了一個不錯的工具&#xff0c;可以讓大家在看代碼的時候一鍵生成C#依賴的類圖。非常適合編寫文檔、查看和學習開源項目設計時使用&#xff0c;比如下方就是筆者通過這個工具生成的Microsoft.Exte…

Web服務器 - Apache配置介紹

基本語法 常量的定義與使用&#xff0c;使用關鍵詞 Define 可以定義常量&#xff0c;使用 ${} 插入常量&#xff0c;如下 語法規則說明示列Define定義常量Define SRVROOT “D:/srv/Apache24”${}使用常量ServerRoot “${SRVROOT}”/表示路徑時使用 / 而不使用 \D:/srv/Apache…

點火開關分為4個檔位,分別是off,acc,IG-on,和ST

off全車除了常火&#xff08;如應急燈&#xff0c;時鐘等的記憶功能&#xff09;外&#xff0c;均不供電。acc 是附件檔&#xff0c;部分車載附屬設備供電&#xff0c;如視聽系統&#xff0c;儀表燈&#xff0c;燈光等。也就是說&#xff0c;車停在哪里&#xff0c;發動機不轉&…

h5的formData 上傳文件及.net后臺

先來前端的代碼&#xff1a; html 代碼&#xff1a; <input type"file" id"files" value"" multiple/> js代碼&#xff1a; function init() {var ele_files document.querySelector("#files");ele_files.addEventListener(&qu…

51 Nod 1027 大數乘法【Java大數亂搞】

1027 大數乘法 基準時間限制&#xff1a;1 秒 空間限制&#xff1a;131072 KB 分值: 0 難度&#xff1a;基礎題 給出2個大整數A,B&#xff0c;計算A*B的結果。Input第1行&#xff1a;大數A 第2行&#xff1a;大數B (A,B的長度 < 1000&#xff0c;A,B > 0&#xff09; Out…

關于ASP.NET Core WebSocket實現集群的思考

前言提到WebSocket相信大家都聽說過&#xff0c;它的初衷是為了解決客戶端瀏覽器與服務端進行雙向通信&#xff0c;是在單個TCP連接上進行全雙工通訊的協議。在沒有WebSocket之前只能通過瀏覽器到服務端的請求應答模式比如輪詢&#xff0c;來實現服務端的變更響應到客戶端&…

windows環境下Apache+PHP+MySQL搭建服務器

相關文件下載 下載地址Apachehttps://www.apachehaus.com/cgi-bin/download.plxPHPhttps://windows.php.net/downloadMySQLhttps://dev.mysql.com/downloads/mysql/MySQL MySQL配置 當前使用的MySQL版本是8.0.18&#xff0c;在MySQL根目錄下新建my.ini文件&#xff0c;下面是…

angular.js國際化模塊

最近需要將一個項目轉化成英文的&#xff0c; 于是發現一個angular模塊angular-translate&#xff0c;實現如下&#xff1a; 1.安裝包 bower install angular-translate bower install angular-translate-loader-static-files //然后在頁面引用進去 <script src"/angul…

觸屏網站如何實現返回并刷新

目的 在會員中心等頁面常常會遇到進入內頁修改信息&#xff0c;返回前一個頁面需要更新信息的場景。 思路 用COOKIE記錄當前頁面是否需要刷新&#xff0c;返回之后再刷新一次頁面。 方案 下載js.cookie.js然后引入到項目中 https://github.com/js-cookie/js-cookie 先來一個最簡…

更快,更強的.NET 7 發布了

.NET Conf 2022 在昨晚(11?8?) 11 點 正式開始了&#xff0c;為期三天的會議&#xff08;11?8-10?&#xff09;&#xff0c; 圍繞 .NET 7 展開。相信各位?伙伴都已經開始安裝 .NET 7 正式版本還有以及相關的開發?具。這次 .NET 7 圍繞傳統的 C# &#xff0c;ASP.NET Core…

Web服務器 - Nginx配置介紹

nginx的配置相對簡單&#xff0c;總體來說分為5種模塊 全局塊&#xff1a;配置影響nginx全局的指令。一般有運行nginx服務器的用戶組&#xff0c;nginx進程pid存放路徑&#xff0c;日志存放路徑&#xff0c;配置文件引入&#xff0c;允許生成worker process數等。events塊&…

jvm(Java virtual machine) JVM架構解釋

2019獨角獸企業重金招聘Python工程師標準>>> JVM 架構解釋 每個Java開發者都知道通過JRE【Java運行環境】執行字節碼。 但是很多人都不知道JRE是JVM實現的事實。JVM負責執行字節碼的分析 代碼的解釋和運行。 我們應該了解JVM的架構&#xff0c;這對開發者來說是很重…

Hyper-V 嵌套虛擬化

先決條件運行 Windows Server 2016 或Windows 10 周年更新的 Hyper-V 主機。運行 Windows Server 2016 或Windows 10 周年更新的 Hyper-V VM。配置版本為 8.0 或更高的 Hyper-V VM。采用 VT-x 和 EPT 技術的 Intel 處理器&#xff08;AMD-V技術的暫時不支持&#xff09;>Set…

簡單的面試題簡解思路(搜集)

1. 統計字符串中單詞出現次數 "hi how are you i am fine thank you youtube am am "&#xff0c;統計"you"出現的次數。 方法一 : split() function wordCount(str,word){var str str || "";var word word || "";var strArr s…

WinForm(十五)窗體間通信

在很多WinForm的程序中&#xff0c;會有客戶端之間相互通信的需求&#xff0c;或服務端與客戶端通信的需求&#xff0c;這時就要用到TCP/IP的功能。在.NET中&#xff0c;主要是通過Socket來完成的&#xff0c;下面的例子是通過一個TcpListerner作為監聽&#xff0c;等待TcpClie…

905. 按奇偶排序數組

1// 905. 按奇偶排序數組 2/** 3 * param {number[]} A 4 * return {number[]} 5 */ 6var sortArrayByParity function(A) { 7 return A.filter(value > value % 2 0).concat( 8 A.filter(value > value % 2 1) 9 )10}; 轉載于:https://www.cnblogs.com/…

關于Java開發需要注意的十二點流程

1.將一些需要變動的配置寫在屬性文件中 比如&#xff0c;沒有把一些需要并發執行時使用的線程數設置成可在屬性文件中配置。那么你的程序無論在DEV環境中&#xff0c;還是TEST環境中&#xff0c;都可以順暢無阻地運行&#xff0c;但是一旦部署在PROD上&#xff0c;把它作為多線…

Unity經典游戲教程之:雪人兄弟

版權聲明&#xff1a; 本文原創發布于博客園"優夢創客"的博客空間&#xff08;網址&#xff1a;http://www.cnblogs.com/raymondking123/&#xff09;以及微信公眾號"優夢創客"&#xff08;微信號&#xff1a;unitymaker&#xff09;您可以自由轉載&#x…

使用webpack搭建個性化項目

安裝主包 yarn add webpack webpack-cli webpack-dev-server -D根據項目實際需求安裝loaders&#xff0c;webpack-loaders列表 根據項目實際需求安裝插件&#xff0c; webpack-plugins列表 常用包列表 包名說明webpackwebpack主程序&#xff0c;配置列表webpack-cliwebpack…

.NET周報【11月第1期 2022-11-07】

國內文章開源安全賦能 - .NET Conf China 2022https://mp.weixin.qq.com/s/_tYpfPeQgyEGsnR4vVLzHg.NET Conf China 2022 是面向開發人員的社區峰會&#xff0c;延續 .NET Conf 2022 的活動&#xff0c;慶祝 .NET 7 的發布和回顧過去一年來 .NET 在中國的發展成果&#xff0c;它…