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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > C# >内容正文

C#

C#高级编程9 第17章 使用VS2013-C#特性

發(fā)布時間:2023/12/9 C# 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C#高级编程9 第17章 使用VS2013-C#特性 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

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

編輯定位到

?

如果默認(rèn)勾選了這項,請去掉勾選,因為勾選之后解決方案的目錄會根據(jù)當(dāng)前文件選中。

?可以設(shè)置項目并行生成數(shù)

?

版本控制軟件設(shè)置

所有文本編輯器行號顯示

?

啟用編輯繼續(xù)

?收集調(diào)試信息,將影響性能

?

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

?nuget包源配置,提供了nuget更新的數(shù)據(jù)源

?目標(biāo)框架的設(shè)置影響到項目基礎(chǔ)框架的引用,不同目標(biāo)框架的項目之間不能互相引用。

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

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

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

?windows服務(wù)項目可以選擇啟用本機(jī)調(diào)試,如果出現(xiàn)無法寫入內(nèi)存的錯誤時。

web發(fā)布

?

?

?

?

?

?

?

VS2015....VS2017...

?

C#6.0特性:

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

        

    1. out-variables(Out變量)

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

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

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

    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個字符串的元組,然而當(dāng)我們獲取到值,使用的時候 心已經(jīng)炸了,Item1,Item2,Item3是什么鬼,雖然達(dá)到了我們的要求,但是實在不優(yōu)雅

    那么,在C#7.0中,微軟提供了更優(yōu)雅的方案:(注意:需要通過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");}

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

    static void Main(string[] args){//定義解構(gòu)元組(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的一個小擴(kuò)展,我們只需要這樣寫就行了,如下:

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

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

    那么問題來了,挖掘機(jī)技術(shù)哪家強(qiáng)?!(咳咳,呸 開玩笑)

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

    我們定義一個Add的方法,以O(shè)bject作為參數(shù),返回動態(tài)類型

    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類型的參數(shù),代碼和輸出如下:

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

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

    匹配模式的Case When篩選

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

    我們把上面的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試試,看結(jié)果如下:

    ?

    ?

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

    ?

    首先我們知道 ref關(guān)鍵字是將值傳遞變?yōu)橐脗鬟f

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

    列子代碼如下:

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

    這段代碼最終輸出 "2"

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

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

    ?

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

    這個功能其實是非常有用的,我們可以把值類型當(dāng)作引用類型來進(jìn)行return

    老規(guī)矩,我們舉個栗子,代碼如下:

    很簡單的邏輯..獲取指定數(shù)組的指定下標(biāo)的值

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

    我們編寫測試代碼如下:

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

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

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

    ?

    5.Local Functions (局部函數(shù))

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

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

    使用方法如下:

    ?

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

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

    ?

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

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

    如下:

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

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

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

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

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

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

    ?

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

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

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

    ?

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

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

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

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

    官方的實例展示的主要是意思是:一個數(shù)據(jù),在已經(jīng)緩存的情況下,可以使用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;}}

    調(diào)用的代碼和結(jié)果如下:

    //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);};// 調(diào)用委托 act();Console.Read();}

    上面的代碼,我們連續(xù)調(diào)用了2次,第一次,等待了5秒出現(xiàn)結(jié)果.第二次則沒有等待直接出現(xiàn)結(jié)果和預(yù)期的效果一致.

    ?

    9.Numeric literal syntax improvements(數(shù)值文字語法改進(jìn))

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

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

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

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

    轉(zhuǎn)載于:https://www.cnblogs.com/licin/p/7235007.html

    總結(jié)

    以上是生活随笔為你收集整理的C#高级编程9 第17章 使用VS2013-C#特性的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。