真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

C#7.0語(yǔ)言新特性有哪些

這篇文章將為大家詳細(xì)講解有關(guān)C#7.0語(yǔ)言新特性有哪些,小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

武安網(wǎng)站建設(shè)公司成都創(chuàng)新互聯(lián)公司,武安網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為武安上千提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\外貿(mào)網(wǎng)站制作要多少錢(qián),請(qǐng)找那個(gè)售后服務(wù)好的武安做網(wǎng)站的公司定做!

C#7.0語(yǔ)言增加了許多的新功能,促使專(zhuān)注于數(shù)據(jù)消費(fèi),簡(jiǎn)化代碼和性能。

或許最大的特征是元組(tuples) ,使得它易于有多個(gè)結(jié)果,并從而簡(jiǎn)化代碼是以對(duì)數(shù)據(jù)的形狀為條件的模式匹配。但也有許多其他的一些功能希望將它們結(jié)合起來(lái),讓代碼運(yùn)行更高效,更明確,從而獲得更多的創(chuàng)造性。如果有哪些運(yùn)行不是你想要的或者有想改進(jìn)的功能,在Visual Studio的窗口頂部使用“send feedback”功能將結(jié)果反饋給我們。在我所描述的許多功能在Preview 4還沒(méi)有辦法充分運(yùn)行,根據(jù)用戶(hù)的反饋結(jié)果,我們將在發(fā)布最終版是增加些新的功能。而必須要指出的是,現(xiàn)有計(jì)劃中的一些功能在最終版也可能會(huì)有所改變或取消。

如果你對(duì)這個(gè)功能設(shè)置感興趣并想學(xué)習(xí)它,在Roslyn GitHub site上可以找到許多的設(shè)計(jì)說(shuō)明和相關(guān)討論。

  輸出(out)變量

目前在C#中,使用out參數(shù)并不像我們想象中那么流暢。在使用out參數(shù)調(diào)用方法時(shí),你首先必須聲明變量傳遞給它。雖然你通常不會(huì)初始化這些變量(他們將通過(guò)該方法后所有被覆蓋),也不能使用VAR來(lái)聲明他們,但是需要指定完整的類(lèi)型:

public void PrintCoordinates(Point p)
{    int x, y; // have to "predeclare"
    p.GetCoordinates(out x, out y);
    WriteLine($"({x}, {y})");
}

在C#7.0,我們?cè)黾恿薕ut變量,作為out參數(shù)傳遞的點(diǎn)來(lái)聲明一個(gè)變量權(quán):

public void PrintCoordinates(Point p)
{
    p.GetCoordinates(out int x, out int y);
    WriteLine($"({x}, {y})");
}

需要注意的是,變量是在封閉塊范圍內(nèi),所以后續(xù)可以使用它們。大多數(shù)類(lèi)型的語(yǔ)句不建立自己的適用范圍,因此out變量通常在聲明中被引入到封閉范圍。

:在Preview 4中,適用范圍規(guī)則更為嚴(yán)格:out變量的作用域?yàn)樗鼈冊(cè)诼暶鞯恼f(shuō)法。因此,上面的例子不會(huì)在后續(xù)的版本中使用。

由于out變量直接聲明作為參數(shù)傳遞給out參數(shù),編譯器通常可以告知類(lèi)型(除非有沖突的過(guò)載)。所以這是很好用VAR,而不是一個(gè)類(lèi)型來(lái)聲明它們:

p.GetCoordinates(out var x, out var y);

out參數(shù)的一個(gè)常見(jiàn)的用途是Try...模式,其中out參數(shù)一個(gè)boolean return表示成功,out參數(shù)進(jìn)行得到的結(jié)果:

public void PrintStars(string s)
{    if (int.TryParse(s, out var i)) { WriteLine(new string('*', i)); }    else { WriteLine("Cloudy - no stars tonight!"); }
}

:Preview 4處理的比較好的地方在于只是用if語(yǔ)句定義它。

計(jì)劃允許“wildcards”作為out參數(shù)以及在*的形式,忽視不重要的out參數(shù):

p.GetCoordinates(out int x, out *); // I only care about x

注:wildcards能否把它變成C#7.0還是個(gè)未知數(shù)。

  模式匹配

C# 7.0 引入了模式的概念,抽象地說(shuō),這是一種語(yǔ)法成分可以用來(lái)測(cè)試一個(gè)值是否有一個(gè)一定的“形”以及在它起作用時(shí)從值里面獲取到的額外信息。

下面是 C# 7.0 中關(guān)于模式的例子:

  • c 的常量模式(c 是C#中的一個(gè)常量表達(dá)式),用于測(cè)試輸入的參數(shù)是否和 c 相等

  • T x 的類(lèi)型模式(T 是一個(gè)類(lèi)型,x 是一個(gè)標(biāo)識(shí)符),用于測(cè)試輸入的參數(shù)是否有類(lèi)型 T,如果有,提取輸入?yún)?shù)的值到一個(gè) T 類(lèi)型的新 x 變量中。

  • var x 變量模式(x 是一個(gè)標(biāo)識(shí)符),通常會(huì)匹配并簡(jiǎn)單地將輸入?yún)?shù)的值放進(jìn)一個(gè)新變量 x 中

這是個(gè)開(kāi)始,模式是一種新的 C# 語(yǔ)言元素,而且我們將來(lái)可以把它們更多地增加到 C# 中。

在 C# 7.0 中,我們正在使用模式以增強(qiáng)兩種已存在的語(yǔ)言結(jié)構(gòu):

  • is 表達(dá)式現(xiàn)在在右邊可以有一個(gè)模式,而不只是一個(gè)類(lèi)型

  • case 子句在 switch 語(yǔ)句中現(xiàn)在可以通過(guò)模式匹配,而不僅僅是常量值

在將來(lái)的C#中,我們或許會(huì)增加更多能使用模式的地方。

  帶模式的 Is 表達(dá)式

這是一個(gè)使用帶有常量模式和類(lèi)型模式的 is 表達(dá)式的例子:

public void PrintStars(object o)
{    if (o is null) return;     // constant pattern "null"    if (!(o is int i)) return; // type pattern "int i"
    WriteLine(new string('*', i));
}

正如你所看到的,模式變量(變量通過(guò)模式引入)與先前描述的 out 變量有些類(lèi)似,他們可以在表達(dá)式中被聲明,而且可以在它們最近的周?chē)秶鷥?nèi)被使用。也像 out 變量那樣,模式變量是易變的,

: 就像 out 變量一樣,嚴(yán)格的范圍規(guī)則適用于 Preview 4.

模式和 Try 方法通常會(huì)一起出現(xiàn):

if (o is int i || (o is string s && int.TryParse(s, out i)) { /* use i */ }

  帶模式的 Switch 語(yǔ)句

我們正在泛化 switch 語(yǔ)句,因此:

  • 你可以在任何類(lèi)型上使用 switch(不僅僅是原始類(lèi)型)

  • 可以在 case 子句中使用模式

  • Case 子句可以擁有額外的條件

這里是一個(gè)簡(jiǎn)單的例子:

switch(shape)
{
    case Circle c:
        WriteLine($"circle with radius {c.Radius}");
        break;
    case Rectangle s when (s.Length == s.Height):
        WriteLine($"{s.Length} x {s.Height} square");
        break;
    case Rectangle r:
        WriteLine($"{r.Length} x {r.Height} rectangle");
        break;
    default:
        WriteLine("");
        break;
    case null:
        throw new ArgumentNullException(nameof(shape));
}

有幾件關(guān)于這個(gè)新擴(kuò)展的 switch 語(yǔ)句的事需要注意:

  • case 子句的順序現(xiàn)在很重要:就像 catch 子句,case 子句不再是必然不相交的,第一個(gè)子句匹配的將被選擇。因此這里重要的是上面代碼中 square case 比 rectangle case 來(lái)得要早。也是和 catch 子句一樣,編譯器會(huì)通過(guò)標(biāo)記明顯不能到達(dá)的情況來(lái)幫助你。在這之前,你永遠(yuǎn)無(wú)法知道評(píng)價(jià)的順序,所以這不是一個(gè)重大改變的特性。

  • 默認(rèn)子句總是最后被評(píng)價(jià):即使上面代碼中 null 子句是最后才來(lái),它會(huì)在默認(rèn)子句被選擇前被檢查。這是為了與現(xiàn)有 switch 語(yǔ)義相兼容。然而,好的做法通常會(huì)讓你把默認(rèn)子句放到最后。

  • null 子句在最后不可到達(dá):這是因?yàn)轭?lèi)型模式遵循當(dāng)前的 is 表達(dá)式的例子并且不會(huì)匹配空值。這保證了空值不會(huì)偶然被任何的類(lèi)型模式捎來(lái)第一搶購(gòu)。你必須更明確如何處理它們(或?yàn)槟J(rèn)子句留下他們)。

通過(guò) case ...: 標(biāo)簽引入的模式變量?jī)H存在于相對(duì)應(yīng)的 switch 部分的范圍內(nèi)。

  元組

這是常見(jiàn)的希望從一個(gè)方法返回多個(gè)值的做法。目前可用的選項(xiàng)不是最佳的:

  • Out 參數(shù)。使用笨拙(即便有上面描述到的提升),它們不使用異步的方法運(yùn)行。

  • System.Tuple<...>  返回類(lèi)型。使用累贅并且需要一個(gè)元組對(duì)象的分配。

  • 為每個(gè)方法定制傳輸類(lèi)型:大量的代碼為了類(lèi)型開(kāi)銷(xiāo)的目的僅是臨時(shí)收集一些值

  • 匿名類(lèi)型通過(guò)返回一個(gè) dynamic 返回類(lèi)型。高性能開(kāi)銷(xiāo)并且沒(méi)有靜態(tài)類(lèi)型檢查。

為了在這方面做得更好,C# 添加了tuple types tuple literals:

(string, string, string) LookupName(long id) // tuple return type
{
    ... // retrieve first, middle and last from data storage
    return (first, middle, last); // tuple literal
}

這個(gè)方法目前有效地返回三個(gè)字符串,將其作為元素在元組類(lèi)型里包裹起來(lái)。

方法的調(diào)用者將會(huì)接受到一個(gè)元組,并且可以逐一訪問(wèn)元素。

var names = LookupName(id);
WriteLine($"found {names.Item1} {names.Item3}.");

Item1 等等,是元組元素的默認(rèn)名字,并能夠經(jīng)常被使用。但它們不是太好描述的,因此你可以選擇性地添加更好的一個(gè)。

(string first, string middle, string last) LookupName(long id) // tuple elements have names

現(xiàn)在元組的接受者擁有更多的可描述的名字用于運(yùn)行:

var names = LookupName(id);
WriteLine($"found {names.first} {names.last}.");

你也可以在 tuple literals 中直接指定名字:

return (first: first, middle: middle, last: last); // named tuple elements in a literal

通常來(lái)說(shuō),你可以互相分配元組類(lèi)型無(wú)關(guān)的名字,只要獨(dú)立的元素是可以被分配的,元組類(lèi)型會(huì)自如 轉(zhuǎn)換成其他元組類(lèi)型。特別是對(duì)于 tuple literals ,存在一些限制,這會(huì)警告或提示在常見(jiàn)的錯(cuò)誤的情況下提示,例如偶然交換元素的名字。

注意:這些限制還沒(méi)在 Preview 4 中實(shí)現(xiàn)

元組是值類(lèi)型,而且他們的元素只是公開(kāi)、易變的域。他們的值相等,代表這兩個(gè)元組是相等的(都有相同的哈斯碼)如果它們的元素都結(jié)對(duì)匹配(都有相同的哈斯碼)。

這使得元組對(duì)于在多種返回值下的很多情況十分有用。舉例來(lái)說(shuō),如果你需要一個(gè)有多種鍵的詞典,使用元組作為你的鍵,然后一切東西就會(huì)如常工作。如果你需要在每個(gè)位置有一個(gè)有多種值的列表,使用元組,查找列表等等,程序會(huì)正常運(yùn)行。

注意:元組依賴(lài)一系列底層類(lèi)型,它們?cè)?Preview 4 中不被引入。為了將來(lái)的工作,你可以通過(guò) NuGget 輕易獲取它們: 在 Solution Explorer 中右鍵點(diǎn)擊項(xiàng)目,并選擇“Manage NuGet Packages…” 選擇“Browse”選項(xiàng)卡,檢查“Include prerelease” 并且選擇“nuget.org”作為“Package source” 搜索“System.ValueTuple”并安裝它

  解構(gòu)

另一種消除元組(tuple)的方法是解構(gòu)元組。通過(guò)一個(gè)解構(gòu)聲明語(yǔ)法,把一個(gè)元組(或者其他的值)拆分為幾部分,并且重新定義為新的變量。

(string first, string middle, string last) = LookupName(id1); // deconstructing decla
rationWriteLine($"found {first} {last}.");

在解構(gòu)中可采用var關(guān)鍵字:

(var first, var middle, var last) = LookupName(id1); // var inside

或者把var關(guān)鍵字提取出來(lái),在括號(hào)外:

var (first, middle, last) = LookupName(id1); // var outside

你也可以通過(guò)解構(gòu)賦值來(lái)解構(gòu)一個(gè)現(xiàn)有變量:

(first, middle, last) = LookupName(id2); // deconstructing assignment

不僅僅元組可以被解構(gòu),任何類(lèi)型都可以被解構(gòu),只要有一個(gè)對(duì)應(yīng)的(實(shí)體或者擴(kuò)展)解構(gòu)方法:

public void Deconstruct(out T1 x1, ..., out Tn xn) { ... }

輸出參數(shù)由解構(gòu)之后的結(jié)果值構(gòu)成。

(為什么采用數(shù)據(jù)參數(shù)代替返回一個(gè)元組?這樣,你可以重載多個(gè)不同的數(shù)值)

class Point
{
    public int X { get; }
    public int Y { get; }

    public Point(int x, int y) { X = x; Y = y; }
    public void Deconstruct(out int x, out int y) { x = X; y = Y; }
}

(var myX, var myY) = GetPoint(); // calls Deconstruct(out myX, out myY);

這將成為一種常見(jiàn)模式,包含析構(gòu)函數(shù)和“對(duì)稱(chēng)”解析:

針對(duì)輸出變量,我們計(jì)劃在解構(gòu)中允許使用“通配符”:

(var myX, *) = GetPoint(); // I only care about myX
注:仍然還沒(méi)有確定是否將通配符引入C# 7.0中。

  局部函數(shù)

有時(shí),一個(gè)輔助函數(shù)只在一個(gè)使用它的單一方法內(nèi)部有意義。現(xiàn)在你可以在其他功能體內(nèi)部聲明這些函數(shù)作為一個(gè)局部函數(shù):

public int Fibonacci(int x)
{
    if (x < 0) throw new ArgumentException("Less negativity please!", nameof(x));
    return Fib(x).current;

    (int current, int previous) Fib(int i)
    {
        if (i == 0) return (1, 0);
        var (p, pp) = Fib(i - 1);
        return (p + pp, p);
    }
}

參數(shù)和閉合區(qū)間局部變量可用在局部函數(shù)內(nèi),類(lèi)似lambda表達(dá)式。

舉一個(gè)例子,方法實(shí)現(xiàn)迭代器通常需要嚴(yán)格檢查調(diào)用時(shí)非迭代器封裝方法。(迭代器本身沒(méi)有運(yùn)行,只到調(diào)用MoveNext 才會(huì)運(yùn)行)。局部函數(shù)在這種情況下是完美的:

public IEnumerable Filter(IEnumerable source, Func filter)
{
    if (source == null) throw new ArgumentNullException(nameof(source));
    if (filter == null) throw new ArgumentNullException(nameof(filter));

    return Iterator();

    IEnumerable Iterator()
    {
        foreach (var element in source) 
        {
            if (filter(element)) { yield return element; }
        }
    }
}

如果迭代器是一個(gè)私有方法的下一個(gè)過(guò)濾器,它將有可能被其他成員不小心使用(沒(méi)有參數(shù)檢查)。此外,作為過(guò)濾器,它將需要采取所有的相同的參數(shù),而不是指定域內(nèi)的參數(shù)。

  注:在Preview 4版本中,本地函數(shù)必須在它們被調(diào)用之前聲明。這個(gè)限制將被放松,能調(diào)用讀取直接賦值的局部變量。

  Literal 改進(jìn)

C# 7.0 允許使用“_”作為數(shù)字分隔符在數(shù)字literals中:

var d = 123_456;
var x = 0xAB_CD_EF;

你可以把它放在你想要的位置,提升可讀性。這樣對(duì)數(shù)值沒(méi)有任何影響。

此外,C# 7.0也介紹了二進(jìn)制literals,這樣你可以直接指定二進(jìn)制模式而不必知道十六進(jìn)制符號(hào)。

var b = 0b1010_1011_1100_1101_1110_1111;

  Ref 返回和本地

就像你可以通過(guò)reference(用ref修飾符)在C#中傳遞東西,您現(xiàn)在可以通過(guò)reference return 他們,并通過(guò) reference將它們存儲(chǔ)在局部變量中。

public ref int Find(int number, int[] numbers)
{
    for (int i = 0; i < numbers.Length; i++)
    {
        if (numbers[i] == number) 
        {
            return ref numbers[i]; // return the storage location, not the value
        }
    }
    throw new IndexOutOfRangeException($"{nameof(number)} not found");
}

int[] array = { 1, 15, -39, 0, 7, 14, -12 };
ref int place = ref Find(7, array); // aliases 7's place in the array
place = 9; // replaces 7 with 9 in the array
WriteLine(array[4]); // prints 9

這對(duì)繞過(guò)占位符成為大數(shù)據(jù)結(jié)構(gòu)是非常有用的。舉例來(lái)說(shuō),一個(gè)游戲可能會(huì)在一個(gè)大的預(yù)分配數(shù)組結(jié)構(gòu)中保存其數(shù)據(jù)(為避免垃圾收集暫停)。Methods 可以直接返回一個(gè) reference 到這樣一個(gè)結(jié)構(gòu),且通過(guò)調(diào)用者可以讀取和修改它。

這里有一些限制,以確保這是安全的:

  • 你可以只返回 refs 那些是 “安全返回(safe to return)”的:那些被傳遞給你的,和那些點(diǎn)到對(duì)象的字段。

  • Ref locals被初始化為某一存儲(chǔ)位置,并且不能突變到指向另一個(gè)。

  廣義異步返回類(lèi)型

截至目前為止,在C#調(diào)用異步方法必須要返回void,Task或Task。C#7.0允許以這樣的方式來(lái)定義其它類(lèi)型,從而使它們可以從異步方法返回。

例如,我們計(jì)劃有一個(gè)ValueTask結(jié)構(gòu)類(lèi)型。它是建立在預(yù)防Task 對(duì)象的分配時(shí),異步操作的結(jié)果是已在可等候的時(shí)間的情況下。對(duì)于很多異步場(chǎng)景,比如以涉及緩沖為例, 這可以大大減少分配的數(shù)量,并使性能有顯著提升。

這里有許多其他的方法可以讓您想象自定義“task-like”類(lèi)型是有用的。它不會(huì)是簡(jiǎn)單的正確創(chuàng)建,所以我們不要指望大多數(shù)人推出自己的,但他們很可能將會(huì)開(kāi)始在框架和API展現(xiàn)出來(lái),然后調(diào)用方可以返回并await他們今天做任務(wù)(Tasks)的方式。

   注:廣義異步返回類(lèi)型尚未應(yīng)用在預(yù)覽4。

  更多 Expression-bodied 方法

Expression-bodied 方法、屬性等都是C# 6.0的重大突破,但并不允許他們?cè)诟鞣N各樣的member中使用,C#7.0添加了訪問(wèn)器、構(gòu)造函數(shù)和終結(jié)器等,使更多member可以使用Expression-bodied 方法:

class Person
{
    private static ConcurrentDictionary names = new ConcurrentDictionary();
    private int id = GetId();

    public Person(string name) => names.TryAdd(id, name); // constructors
    ~Person() => names.TryRemove(id, out *);              // destructors
    public string Name
    {
        get => names[id];                                 // getters
        set => names[id] = value;                         // setters
    }
}
注:這些額外的Expression-bodied 方法還沒(méi)有工作在預(yù)覽4。

這是一個(gè)由社區(qū)貢獻(xiàn)的特征,而非微軟C#團(tuán)隊(duì)。并且,開(kāi)源!

在表達(dá)式的中間拋出一個(gè)異常是很容易的,只需要為你自己調(diào)用一個(gè)方法,但在C#7.0中我們?cè)试S在一些地方直接拋出表達(dá)式:

class Person
{
    public string Name { get; }
    public Person(string name) => Name = name ?? throw new ArgumentNullException(name);
    public string GetFirstName()
    {
        var parts = Name.Split(" ");
        return (parts.Length > 0) ? parts[0] : throw new InvalidOperationException("No name!");
    }
    public string GetLastName() => throw new NotImplementedException();
}
 注:拋出表達(dá)式還未在預(yù)覽4工作。

關(guān)于“C#7.0語(yǔ)言新特性有哪些”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。


本文標(biāo)題:C#7.0語(yǔ)言新特性有哪些
網(wǎng)站路徑:http://weahome.cn/article/posooh.html

其他資訊

在線咨詢(xún)

微信咨詢(xún)

電話咨詢(xún)

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部