- ©«¤l
- 65
- ¥DÃD
- 18
- ºëµØ
- 0
- ¿n¤À
- 71
- ÂI¦W
- 0
- §@·~¨t²Î
- WINXP¡B7¡B10¡BSERVER2012
- ³nÅ骩¥»
- Office 2010-2016
- ¾\ŪÅv
- 20
- ©Ê§O
- ¨k
- µù¥U®É¶¡
- 2011-1-27
- ³Ì«áµn¿ý
- 2021-10-7
|
https://blogs.msdn.microsoft.com/msdntaiwan/2017/04/10/c7-new-features/
³o½g¤å³¹¤¶²Ð¤F C# 7.0 ªº·s»yªk¡C³o¤]¬O¦b 2017/03/07 µoªíªº Visual Studio 2017 ¤¤²³¦h·s¥\¯à¤§¤@¡C
¦b C# 7.0 ·s¼W¤F³\¦h¤ä´©ªº»yªk¡A«ÂIÂ\¦b§ïµ½®Ä¯à¡Bºë²µ{¦¡½X¡B¥H¤Î¸ê®Æ¨ú¥Î´XÓ³¡¤À¡C¨ä¤¤³Ì¥Dnªº¥\¯à¤§¤@¬O Tuples, ¯àÅý§A§ó®e©öªº¤@¦¸¶Ç¦^¦hµ§µ²ªG¡A¥t¥~ Pattern Match ·s»yªk«h²¤Æ¤F¼¶¼g°w¹ï¯S©w¸ê®Æ«¬ºA»P±ø¥óªºµ{¦¡½X¡C°£¦¹¤§¥~¡AC# 7.0 ¤]¥]§t¤F¨ä¥L«nªº¦UºØ·s»yªk¤ä´©¡C§Æ±æ©Ò¦³ªº³o¨Ç§ïÅܳ£¯àÅý§A§ó´r§Öªº¼g¥X¦³®Ä²v¡A²¼äªºµ{¦¡½X¡A¦P®É¤]§ó¦³¥Í²£¤O¡C
¦pªG§A«Ü¦n©_§Ú̦p¦ó¾É¤Þ¥X³o¨Ç¥\¯àªº³]p¹Lµ{¡A¥i¥H¬d¾\ C# Language design GitHub ºô¯¸¡A¦b¨ºÃä¥i¥H§ä¨ì³]p»¡©ú¤å¥ó¡A³]p´£®×¡A»P¤j¶qªº°Q½×¤º®e¡C
¦pªG§Aı±o³o½g¤å³¹¤º®e«Ü¼ô±x¡A¤]³\¬O§A´¿¸g¬Ý¹L¥h¦~¤K¤ë¥÷ (2016/08) µoªí¹Lªºª©¥»¡C¦b C# 7.0 ³Ì²×©w®×ªºª©¥»¤¤¦³¤Ö¼Æªº²§°Ê¡A³o¨Ç
²§°Ê³£¨Ó¦Û¥ý«eª©¥»ªº²³¦hÀu¨}ªº¦^õX·N¨£¡C
§Æ±æ§A³ßÅw C# 7.0, ºÉ±¡¨É¨ü¥¦, Happy Hacking !!
Mads Torgersen, C# Language PM
Ķµù:
¬°¤F§ó²M·¡ªºªí¹F³o½g¤å³¹ªº¤º®e¡A½Ķ®É§Ú±Ä¥Î·NĶ¡A¦Ó«D³v¥y½Ķ¡C§Ú¤]·|¾A®É¸É¥R¦r¥y¡AÅý¤å³¹nªí¹Fªº·N¸q§ó²M·¡§¹¾ã¡C
¤Ó¦h±M¦³¦Wµü¡A½¦¨¤¤¤å¤Ï¦Ó¹ï¾\Ū¨S¦³À°§U¡A¦]¦¹³o³¡¤À§Ú«O¯dì¤å¡A¦ý¬O§Ú·|¦bĶµùªº³¡¤ÀÃB¥~¸É¥R»¡©ú¡C
´Á±æ³o¼Ë¯à§ó²M·¡ªºÅýŪªÌ¤F¸Ñ¤º®e¡C
Microsoft-logo ¥»½g¤å³¹¡A±a±z¬Ý¨ì¥H¤U C# 7.0 ·s¥\¯à¡G
Out ÅÜ¼Æ ( out variables )
Pattern Matching (¼Ò¦¡¤Ç°t )
¨Ï¥Î pattern ªº is ªí¹F¦¡
¨Ï¥Î patterns ªº switch ³¯z¦¡
Tuples
Desconstruction (¸Ñºc )
Local functions ( °Ï°ì¨ç¦¡ )
§ï¨}ªº Literal
Ref returns »P ref locals
«D¦P¨Bªº¶Ç¦^«¬§O
§ó¼sªxªº expression bodies ¦¨û
Throw ¹Bºâ¦¡
Out ÅÜ¼Æ (out variables)
¦b¥ý«eª©¥»ªº C# ¤¤¡Aout °Ñ¼Æªº¨Ï¥Î¨Ã¤£¦p§ÚÌ´Á±æªº¨º»òªº¬yºZ¡C©I¥s±a¦³ out °Ñ¼Æªº method ¤§«e¡A§A¥²¶·¥ý«Å§iÅܼÆ
¨Ã¥B±N¥¦·í§@ out ªº°Ñ¼Æ¶Ç»¼¤~¦æ¡C³q±`§A¤£·| (¤]¤£»Ýn) ¥ýªì©l¤Æ³oÅÜ¼Æ (Åܼƪº¤º®e·|¦b³Q©I¥sªº method ¤ºÂмg)¡A¦P®É§A¤]¤£¯à¨Ï¥Î var ªº¤è¦¡¨Ó«Å§i¥¦, §A¥²¶·«Ü©ú½Tªº«ü©w³oÅܼƪº§¹¾ã«¬§O:
public void PrintCoordinates(Point p)
{
int x, y; // have to "predeclare"
p.GetCoordinates(out x, out y);
WriteLine($"({x}, {y})");
}
¦b C# 7.0¡A·s¼W¤F out ÅܼơA¥i¥H¦b¶Ç»¼ out °Ñ¼Æ®É¦P®É«Å§i³oÓÅܼÆ:
public void PrintCoordinates(Point p)
{
p.GetCoordinates(out int x, out int y);
WriteLine($"({x}, {y})");
}
½Ð¯d·N¡A³oÓÅܼƦb¥]§t¥¦¥»¨ªº { } «Ê³¬°Ï¶ô½d³ò¤º¡A©Ò¥H±µÄò«Å§i«á±ªºµ{¦¡½X¥i¥Hª½±µ¨Ï¥Î³o¨ÇÅܼơC
¦h¼ÆÃþ¦ü«¬ºAªº»yªk¨S¦³«ü©w¥iµø½d³ò¡A¸ÓÅܼƥiµø½d³ò´Nµ¥¦P©ó«Å§i¥Lªº°Ï¶ô½d³ò¡C
³q±` out ÅܼƳ£·|ª½±µ³Q«Å§i¬°¶Ç»¼ªº°Ñ¼Æ¡A½sĶ¾¹³q±`¯àª½±µ§P©w°Ñ¼Æªº«¬§O¬°¦ó (°£«D method ¥]§t¼ÆÓ¤¬¬Û½Ä¬ð
ªº overloads ¦ÓµLªk§P©w)¡A¦]¦¹¥i¥Hª½±µ¨Ï¥Î var ªº¤è¦¡¨Ó«Å§i¥¦:
p.GetCoordinates(out var x, out var y);
¤@¯ë¨Ó»¡¡A§Ú̱`±`¦b Try... ³oÃþªº¨Ï¥Î¼Ò¦¡¤¤¥Î¨ì out °Ñ¼Æ¡A¥¦·|¶Ç¦^ true ©Î¬O false ¨Ó¥Nªí°õ¦æ¦¨¥\»P§_¡A¦P®ÉÂÇµÛ out °Ñ¼Æ¨Ó¶Ç¦^¦¨¥\°õ¦æ«áªºµ²ªG:
public void PrintStars(string s)
{
if (int.TryParse(s, out var i)) { WriteLine(new string('*', i)); }
else { WriteLine("Cloudy - no stars tonight!"); }
}
¦pªG§A¤£¦b·N¬YÓ out °Ñ¼Æªº¶Ç¦^µ²ªG¡A¥i¥H¨Ï¥Î _ ¥Nªí©¿²¤¥¦:
p.GetCoordinates(out var x, out _); // I only care about x
Pattern Matching (¼Ò¦¡¤Ç°t)
C# 7.0 ¶}©l¤Þ¤J¤F patterns (¼Ò¦¡) ªº·§©À¡C©â¶Hªº¨Ó»¡¡A¥L¬O¥i¥H§P©w¸ê®Æ¬O§_¨ã³Æ¤@©w "§Îª¬"(Shape) ªº»yªk¤¸¯À¡A¨Ã±q¸Ó¼ÆȤ§¤¤´£¨ú»Ýnªº¸ê°T¡C
Ķµù:
Shape, ¥Nªí¸ê®Æªº "§Îª¬", ºë½Tªº¨Ó»¡¥]§t¸ê®Æ¥»¨«¬§O¥]§tþ¨Ç¦¨û? ³o¨Ç¦¨ûªº¼ÆȬO§_¸¨¦b¹w´Áªº½d³ò?
patterns ¥i¥HÅý§PÂ_¸ê®Æ "§Îª¬" ªºµ{¦¡½X§ó¬°Â²¼ä©ú½T¡C
Á|¨Ò¨Ó»¡¡AC# 7.0 ¤ä´©ªº patterns ¦³³o´XºØ:
Constant Patterns (±`¼Æ¼Ò¦¡, ¥H c ªí¥Ü¡Ac ¬O C# ªº±`¼Æªí¹F¦¡), ´ú¸Õ¿é¤Jªº¼ÆȬO§_»P c ¬Ûµ¥¡C
Type Patterns (Ãþ«¬¼Ò¦¡, ¥H T x ªí¥Ü¡AT ¥Nªí«¬§O¡A¦Ó x ¬OÃѧO¦WºÙ), ´ú¸Õ¿é¤Jªº¼ÆȬO§_ÄÝ©óÃþ§O T? ¦pªG¬Oªº¸Ü´N§â¿é¤Jªº¼ÆÈ©ñ¨ìÃþ«¬¬° T ªºÅÜ¼Æ x ¤¤¡C
Var Patterns (ÅܼƼҦ¡, ¥H var x ªí¥Ü, x ¬OÃѧO¦WºÙ), ³oºØ¼Ò¦¡¤U¥Ã»··|¤Ç°t¦¨¥\¡A¦¹®É x ªº«¬§O»P¿é¤Jªº¼ÆȬۦP¡A³o¼Ò¦¡¤U¥u¬O²³æªº§â¿é¤Jªº¼ÆÈ©ñ¨ì x ¤§¤¤¡C
³o¨Ç¥u¬Opµe¤¤ªº²Ä¤@¨B - pattern (¼Ò¦¡) ¬O C# ·s«¬ºAªº»yªk¤¸¯À¡A§ÚÌ´Á±æ¥¼¨Ó¯àÄ~Äò·s¼W§ó¦hªº¥\¯à¡C
¦b C# 7.0 §Ú̥Πpattern ¨Ó¼W±j¨âºØ¬J¦³ªº»yªkµ²ºc:
is expression (is ªí¹F¦¡) ²{¦b¥i¥H¦b¥k¤è¥[¤W pattern¡A¦b¤§«e«h¥u¯à©w¸q«¬§O¡C
switch ³¯z¦¡¤¤ªº case ¤l¥y¡A²{¦b¥i¥H¤ñ¹ï¼Ò¦¡¬O§_²Å¦X¡A¹L¥h«h¥u¤ä´©±`¼Æ¼ÆÈ¡C
¦b¥¼¨Óªº C# §ÚÌ·|¼W¥[§ó¦h¾A¥Î pattern ªº»yªk¡C
¨Ï¥Î pattern ªº is ªí¹F¦¡
¨Ó¬Ý¬Ý¨Ï¥Î constant patterns »P type patterns ªº is expression ¨Ï¥Î½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));
}
¦p©Ò¨£¡Apattern ÅÜ¼Æ - ¥Ñ pattern ¤Þ¤JªºÅܼơA¸ò«e±¤¶²Ðªº out ÅܼƫD±`¬Û¦ü¡A§A¥i¥H«Å§i¦bªí¹F¦¡¤§¤¤¡A¦Ó¥B¥i¥Hª½±µ´Nªñ¦b¦P¥i¬O½d³ò¤ºª½±µ¨Ï¥Î¥L¡C
¸ò out Åܼƫܬۦüªº¦a¤è¬O¡A¼Ò¦¡ÅܼƬO¥iÅܰʪº¡A§Ú̱`±N out ÅܼƻP pattern ÅܼơA²ÎºÙ¬° expression ÅܼơC
Patterns ±`»P Try... method ¤@°_¨Ï¥Î:
if (o is int i || (o is string s && int.TryParse(s, out i)) { /* use i */ }
¨Ï¥Î patterns ªº switch ³¯z¦¡
¦b C# 7.0¡A§Ṳ́]ÂX¤j¤F switch ³¯z¦¡ªºÀ³¥Î½d³ò:
switch ³¯z¦¡²{¦b¥i¥H¹B¥Î¦b©Ò¦³«¬§O (¤£¦A¥u©ó°ò¥»Ãþ«¬)
patterns ¥i¥H¥Î¦b case ¤l¥y
case ¤l¥y¥i¥Hªþ¥[±ø¥ó§PÂ_¦¡
³oÃ䦳¹ïÀ³ªº½d¨Òµ{¦¡½X:
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("<unknown shape>");
break;
case null:
throw new ArgumentNullException(nameof(shape));
}
³o¸Ì¦³´XÓ switch ³¯z¦¡·s¼WªºÂX¥R¥\¯à:
case ¤l¥yªº¶¶§Ç¬O«nªº:
´N¦p¦P catch ¤l¥y¤@¼Ë¡A¦hÓ case ¤l¥y¤§¶¡¤£¦A¬O¨S¦³¶¶§ÇÃöÁpªº¡A¦Ó²Ä¤@ӲŦX±ø¥óªº case ¤l¥y·|³Q¿ï¤¤¡C³oÂI«D±`«n¡A®³¤W¤@Ó½d¨Òµ{¦¡½X¨Ó»¡¡A¥Nªí¥¿¤è§Îªº³oÓ case ¤l¥y (Ķµù: case Rectangle s when (s.Length == s.Height):) À³¸Ón±Æ¦b¥Nªíªø¤è§Îªº case ¤l¥y (case Rectangle r:) «e±¡Aµ²ªG¤~·|¥¿½T¡C¥t¥~¡A´N¹³ catch ¤l¥y¤@¼Ë¡A½sĶ¾¹¥i¥H¼Ð¥Ü¥X¥Ã»·µLªk°õ¦æ¨ìªºµ{¦¡½X¨Ó¨ó§U§A¡C¦b³o¤§«e¡A§AµLªk¤]¤£»Ýn«ü©w¦hÓ case ¤§¶¡ªºµû¦ô¶¶§Ç¡A©Ò¥H³o¨Ã¤£¬OÓ¯}Ãa©Êªº§ïÅÜ (breaking change)¡C
default ¤l¥y¥Ã»··|³Ì«á¤~µû¦ô:
§Y¨Ï¦b¤Wzªº¨Ò¤l¤¤¡Anull case ¤l¥y³QÂ\¦b³Ì«á¡A¥L¤´µM·|¦b default ¤l¥y¤§«e³QÀˬd¡C³o¼Ëªº³]p¬O¬°¤F»P²{¦³ªº switch ³¯z¥y«O«ù¬Û®e¡CµM¦Ó¡A¦nªº°µªk³q±`·|©ú½Tªº±N default ¤l¥yÂ\¦b³Ì«á±¡C
Â\¦b³Ì«á±ªº null case ¤l¥y¨Ã¤£·|µLªk³Q³Q°õ¦æ¨ì:
¦]¬° type patterns (Ãþ«¬¼Ò¦¡) ¨Ì´` is expression ªº¨Ò¤l¡A¤£·|»P null ¤l¥y¤Ç°t¡C³o¥i¥H½T«O null ¤l¥y¤£·|¤£¤p¤ß³Q¥ô¦óªº type patterns (Ãþ«¬¼Ò¦¡) µ¹·m¨«¡A§A¥²¶·§ó²M·¡¸Ó¦p¦ó³B²z³oºØª¬ªp (©Î¬O§â¥¦¯dµ¹ default ¤l¥y¨Ó³B²z)¡C
¥Ñ case ... ¤Þ¶iªº pattern ÅÜ¼Æ ¡A¥Lªº¥iµø½d³ò¥u©ó¹ïÀ³ªº switch °Ï¬q¡C
Tuples
·Qn±q¤@Ó method ¶Ç¦^¤@Ó¥H¤Wªº¶Ç¦^ȬOÆZ±`¨£ªºª¬ªp¡C¦ý¬O¥Ø«e C# ª©¥»¹ï³o»Ý¨D¯à´£¨Ñªº§@ªk³£¤£°÷¦n¡C²{¦³ªº§@ªk¦³:
out °Ñ¼Æ:
¨Ï¥Î¤W«Ü²ÖÂØ (§Y¨Ï¦b«e±ªº³¡¤À¤w¸g¤¶²Ð¤F§ï¨}ªº»yªk)¡A¦Ó¥B³o¤è¦¡¤]µLªk·f°t async method ¤@°_¨Ï¥Î¡C
¨Ï¥Î System.Tuple<...> «¬§O¨Ó¶Ç¦^È:
»Ýn¤â°Ê°t¸m¤@Ó tuple ª«¥ó¡A¦P®É¤]»Ýn¼g¨Ç¤¾ªøªº code ¤~¯à¿ì¨ì¡C
´À¨CÓ method ³£¦Ûq±MÄݪº¶Ç¦^È«¬§O:
±oÃB¥~¼g¤j¶qªº code ¨Ó§¹¦¨³o¥ó¨Æ¡A¦ý¬O¥Øªº¥u¬O¼È®É±N¦hÓ¼ÆȲզX°_¨Ó¦Ó¤w¡C
¨Ï¥Î dynamic ¨Ó¶Ç¦^°Î¦Wªº«¬§O (anonymous types):
µLªk°µ¨ìÀRºA«¬§OÀˬd¡A¦P®É±N·|¥I¥X«Ü°ªªº®Ä¯à¥N»ù¡C
¬°¤FÅý³o¥ó¨Æ°µ±o§ó¦n¡AC# 7.0 ·s¼W¤F tuple types ¤Î tuple literals ªº»yªk:
(string, string, string) LookupName(long id) // tuple return type
{
... // retrieve first, middle and last from data storage
return (first, middle, last); // tuple literal
}
³o method ²{¦b¯à§ó¦³®Ä²vªº¶Ç¦^¤TÓ¦r¦ê«¬§Oªº¶Ç¦^ȤF¡A³o½d¨Ò±N¤TÓ¦r¦ê¥]¦¨¤@Ó tuple¡C
©I¥s³o method ªºµ{¦¡½X±N·|¦¬¨ì¦^¶Çªº tuple ª«¥ó¡A¥B¯à³z¹L tuple ª«¥óÓ§O¦s¨ú³o¨Ç«Ê¸Ë¦b¤ºªº¸ê®Æ:
var names = LookupName(id);
WriteLine($"found {names.Item1} {names.Item3}.");
¨ä¤¤ Item1 µ¥µ¥¡A¬° tuple ¤ºªº¤¸¯À¹w³]ªº¦WºÙ¡A³o¤èªk¯à¥¿±`¹B§@, ¦ý¬O³o©R¦W¤è¦¡²×¨s¤£¯à«Ü¯à²M·¡ªí¹F¥Î³~¡C©Ò¥H§AÄ@·Nªº¸Ü¥i¥H©ú½Tªº´À¥¦Ì«ü©w§ó¾A¦Xªº¦WºÙ:
(string first, string middle, string last) LookupName(long id) // tuple elements have names
²{¦b³oÓ tuple ªº¤¸¯À¯à¥Î§ó¶K¤Áªº¦WºÙ¨Ó¦s¨ú¤§¤ºªº¤¸¯À¤F:
var names = LookupName(id);
WriteLine($"found {names.first} {names.last}.");
§A¤]¥i¥Hª½±µ¦b tuple literals ¤º«ü©w¤¸¯Àªº¦WºÙ:
return (first: first, middle: middle, last: last); // named tuple elements in a literal
¤@¯ë¨Ó»¡¡A§A¥i¥H¤¬¬Û«ü¬£ tuple ªºÅܼơA¦Ó¤£¥ÎºÞ¥Lªº¦WºÙ¬°¦ó: ¥unÓ§Oªº¤¸¯À³£¥i¥H³Q«ü¬£¡Atuple «¬§O¥i¥H¦Û¥ÑÂà´«¬°¨ä¥Lªº tuple «¬§O¡C
Tuples ¬O value types, ¦Ó¥B¥¦¥]§tªº¤¸¯À³£«Ü³æ¯Âªº³Q¼Ð¥Ü¬° public, ³£¬O¥i²§°ÊªºÄæ¦ì (mutable fields)¡C¥¦Ì¬O "¼ÆȬ۵¥" (value equality) ªº¡A
·N«ä¬O¥un¨âÓ tuples ªº©Ò¦³¹ïÀ³ªº¤¸¯À³£¬O¬Ûµ¥ªº (¦Ó¥B hash code ¤]¥²¶·¬Û¦P)¡A¨º³o¨âÓ tuples ´N¬O¬Ûµ¥ªº (hash code ¤]·|¬Û¦P) ¡C
°£¤F¶Ç¦^¦hӶǦ^Ȫº±¡ªp¤§¥~¡A¦b¨ä¥L¦a¤è tuples ¤]«Ü¦³¥Î¡C¨Ò¦p¡A¦pªG§A»Ýn¤@Ó¥]§t¦hÓ Key ªº Dictionary¡A§A¥u»Ýn®³ tuple ·í§@ Dictionary ªº Key ´N¥i¥H¤F¡C¦pªG§A»Ýn¦b List ¤ºªº¤@Ó¤¸¯À©ñ¸m¦hÓ¤£¦Pªº¼ÆÈ¡A¥un¨Ï¥Î tuple «¬§O¨Ã¥B·j´M³oÓ List¡C¦b³o¨Ç±¡ªp¤¤¡Atuple ³£¯à¥¿±`¹B§@¡C
Tuples ªº¹ê§@¥²¶·¨Ì¾a©³¼hªºªx«¬µ²ºc«¬§O (generic struct types): ValueTuple<...>¡C¦pªG§A¨Ï¥Îªº target framework ª©¥»ÁÙ¥¼¥]§t¥¦¡A§A¥u»Ýn³z¹L NuGet ¨ú±o¥ĻY¥i:
¦b "¤è®×Á`ºÞ" ¤ºªº "±M®×" ¤W«ö¥kÁä¡A¿ï¾Ü "ºÞ²z NuGet ®M¥ó..."
¿ï¾Ü "ÂsÄý" ¶ÅÒ¡A¦P®É¦b "®M¥ó¨Ó·½" ¶µ¥Ø¤¤¿ï¾Ü "nuget.org"
·j´M "System.ValueTuple" ¨Ã¦w¸Ë |
|