亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

編寫高質量代碼改善C#程序的157個建議——建議61:避免在finally內撰寫無效代碼

2019-11-14 14:06:24
字體:
來源:轉載
供稿:網友

建議61:避免在finally內撰寫無效代碼

在闡述建議之前,需要先提出一個問題:是否存在一種打破try-finally執行順序的情況,答案是:不存在(除非應用程序本身因為某些很少出現的特殊情況在try塊中退出)。應該始終認為finally內的代碼會在方法return之前執行,哪怕return在try塊中。

正是這點,可能會讓你寫出無效的代碼,有時候,這樣的無效代碼會是一個隱藏很深的Bug。

看下面代碼:

        PRivate static int TestIntReturnBelowFinally()        {            int i;            try            {                i = 1;            }            finally            {                i = 2;                Console.WriteLine("/t將int結果改為2,finally執行完畢");            }            return i;        }

返回值是2。

但是:

        private static int TestIntReturnInTry()        {            int i;            try            {                return i = 1;            }            finally            {                i = 2;                Console.WriteLine("/t將int結果改為2,finally執行完畢");            }        }

返回值是1。

再看下面代碼:

        static User TestUserReturnInTry()        {            User user = new User() { Name = "Mike", BirthDay = new DateTime(2010, 1, 1) };            try            {                return user;            }            finally            {                user.Name = "Rose";                user.BirthDay = new DateTime(2010, 2, 2);                Console.WriteLine("/t將user.Name改為Rose");            }        }

user類:

    class User    {        public string Name { get; set; }        public DateTime BirthDay { get; set; }    }
View Code

TestUserReturnInTry方法返回的User中,Name的值已經改為Rose了。

 

現在來解釋為什么上面3個函數會有3種結果。查看TestIntReturnBelowFinally的finally部分的IL代碼:

  finally  {    IL_0004:  ldc.i4.2    IL_0005:  stloc.0    IL_0006:  ldstr      bytearray (09 00 06 5C 69 00 6E 00 74 00 D3 7E 9C 67 39 65   // .../i.n.t..~.g9e                                    3A 4E 32 00 0C FF 66 00 69 00 6E 00 61 00 6C 00   // :N2...f.i.n.a.l.                                    6C 00 79 00 67 62 4C 88 8C 5B D5 6B )             // l.y.gbL..[.k    IL_000b:  call       void [mscorlib]System.Console::WriteLine(string)    IL_0010:  endfinally  }  // end handler  IL_0011:  ldloc.0  IL_0012:  ret}

IL_0004: ldc.i4.2”首先將2壓入棧頂

IL_0005: stloc.0”將最頂層堆棧的值,也就是2賦值給本地變量,也就是 i (index 0)

IL_0011: ldloc.0”將本地變量 i (index 0)的值再次壓入棧

IL_0012: ret”結束函數,同時把棧內的返回值壓入調用者的棧中。就函數將2賦值給了返回值。

 

看方法TestIntReturnInTry()的Debug版本的IL代碼:

.method private hidebysig static int32  TestIntReturnInTry() cil managed{  // 代碼大小       27 (0x1b)  .maxstack  2  .locals init ([0] int32 i,           [1] int32 CS$1$0000)  IL_0000:  nop  .try  {    IL_0001:  nop    IL_0002:  ldc.i4.1    IL_0003:  dup    IL_0004:  stloc.0    IL_0005:  stloc.1    IL_0006:  leave.s    IL_0018  }  // end .try  finally  {    IL_0008:  nop    IL_0009:  ldc.i4.2    IL_000a:  stloc.0    IL_000b:  ldstr      bytearray (09 00 06 5C 69 00 6E 00 74 00 D3 7E 9C 67 39 65   // .../i.n.t..~.g9e                                    3A 4E 32 00 0C FF 66 00 69 00 6E 00 61 00 6C 00   // :N2...f.i.n.a.l.                                    6C 00 79 00 67 62 4C 88 8C 5B D5 6B )             // l.y.gbL..[.k    IL_0010:  call       void [mscorlib]System.Console::WriteLine(string)    IL_0015:  nop    IL_0016:  nop    IL_0017:  endfinally  }  // end handler  IL_0018:  nop  IL_0019:  ldloc.1  IL_001a:  ret} // end of method Program::TestIntReturnInTry

TestIntReturnInTry在IL中創建了兩個本地變量 i 和CS$1$0000 ,i 存儲的是1,然后finally中 i 被賦值為2。調用者真正得到的是由IL創建的CS$1$0000所對應的值。用Reflector查看C#代碼:

private static int TestIntReturnInTry(){    int i;    int CS$1$0000;    try    {        CS$1$0000 = i = 1;    }    finally    {        i = 2;        Console.WriteLine("/t將int結果改為2,finally執行完畢");    }    return CS$1$0000;}

實際上,finally中i=2沒有任何意義,所以在本函數的release版本中,IL中找不到對應的代碼:

.method private hidebysig static int32  TestIntReturnInTry() cil managed{  // 代碼大小       17 (0x11)  .maxstack  1  .locals init ([0] int32 CS$1$0000)  .try  {    IL_0000:  ldc.i4.1    IL_0001:  stloc.0    IL_0002:  leave.s    IL_000f  }  // end .try  finally  {    IL_0004:  ldstr      bytearray (09 00 06 5C 69 00 6E 00 74 00 D3 7E 9C 67 39 65   // .../i.n.t..~.g9e                                    3A 4E 32 00 0C FF 66 00 69 00 6E 00 61 00 6C 00   // :N2...f.i.n.a.l.                                    6C 00 79 00 67 62 4C 88 8C 5B D5 6B )             // l.y.gbL..[.k    IL_0009:  call       void [mscorlib]System.Console::WriteLine(string)    IL_000e:  endfinally  }  // end handler  IL_000f:  ldloc.0  IL_0010:  ret} // end of method Program::TestIntReturnInTry

用Reflector查看release版本中C#代碼:

private static int TestIntReturnInTry(){    int CS$1$0000;    try    {        CS$1$0000 = 1;    }    finally    {        Console.WriteLine("/t將int結果改為2,finally執行完畢");    }    return CS$1$0000;}

 

再解釋第三個方法TestUserReturnInTry為什么返回的是“Rose”。Reflector查看release版本中C#代碼:

private static User TestUserReturnInTry(){    User CS$1$0000;    User <>g__initLocal0 = new User {        Name = "Mike",        BirthDay = new DateTime(0x7da, 1, 1)    };    User user = <>g__initLocal0;    try    {        CS$1$0000 = user;    }    finally    {        user.Name = "Rose";        user.BirthDay = new DateTime(0x7da, 2, 2);        Console.WriteLine("/t將user.Name改為Rose");    }    return CS$1$0000;}

 

User是引用類型, CS$1$0000 = user;說明CS$1$0000和user指向的是同一個對象,當在finally中 user.Name = "Rose"時CS$1$0000的Name也會變為“Rose”。所以返回的CS$1$0000的Name為“Rose”。

 

再舉一個例子:

 

        private static User TestUserReturnInTry2()        {            User user = new User() { Name = "Mike", BirthDay = new DateTime(2010, 1, 1) };            try            {                return user;            }            finally            {                user.Name = "Rose";                user.BirthDay = new DateTime(2010, 2, 2);                user = null;                Console.WriteLine("/t將user置為anull");            }        }

 

返回的結果不是null,而一個Name=“Rose”,BirthDay = new DateTime(2010, 2, 2)的User對象。Reflector查看release版本中C#代碼:

private static User TestUserReturnInTry2(){    User CS$1$0000;    User <>g__initLocal1 = new User {        Name = "Mike",        BirthDay = new DateTime(0x7da, 1, 1)    };    User user = <>g__initLocal1;    try    {        CS$1$0000 = user;    }    finally    {        user.Name = "Rose";        user.BirthDay = new DateTime(0x7da, 2, 2);        user = null;        Console.WriteLine("/t將user置為anull");    }    return CS$1$0000;}

 

CS$1$0000和user指向的是同一個對象,當在finally中 user=null 時,只是user指向為null了,CS$1$0000指向的對象并沒有變。

 

 

轉自:《編寫高質量代碼改善C#程序的157個建議》陸敏技


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
懂色av影视一区二区三区| 中文字幕亚洲一区二区三区五十路| 国产精品视频专区| 国产精品精品视频| 国产欧美日韩精品丝袜高跟鞋| 国产精品∨欧美精品v日韩精品| 日本国产一区二区三区| 国产精品成久久久久三级| 日韩精品福利在线| 亚洲黄色在线观看| 日韩av电影在线免费播放| 欧美精品国产精品日韩精品| 欧美午夜激情小视频| 久久影院中文字幕| 成人免费直播live| 青青草精品毛片| 久久久久久久91| 亚洲aa中文字幕| 精品综合久久久久久97| 国产成人在线亚洲欧美| 97香蕉久久超级碰碰高清版| 国产成人涩涩涩视频在线观看| 亚洲色图av在线| 欧美激情小视频| 日韩欧美在线播放| 日韩欧美精品网址| 国产精品久久97| 亚洲japanese制服美女| 久久精品99无色码中文字幕| 国产亚洲精品高潮| 亚洲国产精品成人一区二区| 欧美性jizz18性欧美| 91久久久久久久一区二区| 久久久久久91香蕉国产| 国产精品白丝av嫩草影院| xvideos成人免费中文版| 久久国产精品久久久久| 一本一本久久a久久精品牛牛影视| 欧美激情成人在线视频| 亚洲人成电影在线观看天堂色| 8090理伦午夜在线电影| 在线观看欧美日韩国产| 亚洲精品一区中文| 国产精品久久久久久影视| 亲爱的老师9免费观看全集电视剧| 在线成人免费网站| 91美女福利视频高清| 成人h片在线播放免费网站| 国产精品高清网站| 免费成人高清视频| 欧美激情视频网址| 国产999在线观看| 97在线视频免费看| 欧美放荡办公室videos4k| 精品无人国产偷自产在线| 欧美日韩免费在线| 一本色道久久88亚洲综合88| 国产成人97精品免费看片| 精品视频www| 欧美精品免费在线观看| 亚洲欧美国内爽妇网| 久久久久久高潮国产精品视| 亚洲第一福利网站| 国外成人在线直播| 国产剧情日韩欧美| 色综合老司机第九色激情| 精品日韩中文字幕| 欧美在线观看视频| 日韩中文字幕国产| 黄色91在线观看| 精品日韩中文字幕| 久久精品国产v日韩v亚洲| 777国产偷窥盗摄精品视频| 尤物yw午夜国产精品视频| 国产精品久久久久久久久男| 中文字幕国产亚洲2019| 亚洲乱码国产乱码精品精| 欧美自拍视频在线| 国产精品草莓在线免费观看| 亚洲а∨天堂久久精品9966| 欧美激情aaaa| 欧美大全免费观看电视剧大泉洋| 亚洲激情国产精品| 日韩精品福利在线| 日本成人在线视频网址| 国产精品国语对白| 97欧美精品一区二区三区| 日韩欧美在线视频日韩欧美在线视频| 欧美性视频精品| 懂色av一区二区三区| 91麻豆国产精品| 国产97在线观看| 国产精品偷伦一区二区| 亚洲a级在线播放观看| 亚洲视频在线观看| 国产成+人+综合+亚洲欧美丁香花| 亚洲第一色在线| 亚洲国产天堂久久综合网| 国产在线精品自拍| 日韩成人av网址| 91久久精品国产91性色| 日韩av在线免费播放| 亚洲黄页网在线观看| 亚洲自拍小视频| 91在线观看免费高清完整版在线观看| 综合av色偷偷网| 97精品视频在线播放| 国产成人精品一区二区三区| 国模吧一区二区三区| 社区色欧美激情 | 欧美日韩在线一区| 欧美视频在线免费看| 国产在线拍揄自揄视频不卡99| 国产精品免费久久久久影院| 色婷婷久久一区二区| 欧美极品少妇全裸体| 国产精品自拍小视频| 日韩成人黄色av| www.欧美视频| 中文欧美在线视频| 亚洲色图国产精品| 欧美极度另类性三渗透| 欧美日韩亚洲高清| 亚洲国产成人久久| 久久中文久久字幕| 日韩在线视频网站| 亚洲精品久久7777777| 欧美日韩成人在线播放| 久久精品成人欧美大片古装| 成人中心免费视频| 欧美在线精品免播放器视频| 国产精品v片在线观看不卡| 精品国产一区二区三区久久久狼| 国产91成人video| 正在播放欧美视频| 日韩大片免费观看视频播放| 久久99精品视频一区97| 精品国产乱码久久久久久天美| 高清欧美性猛交xxxx黑人猛交| 亚洲一区二区三区成人在线视频精品| 国产精品久久久久久久9999| 亚洲色图日韩av| 狠狠躁夜夜躁人人爽超碰91| 国产亚洲激情视频在线| 日韩av成人在线| 精品日韩中文字幕| 欧美成人免费视频| 欧美日韩国产成人高清视频| 国产精品一区二区三| 日韩在线视频网站| 欧美成人激情视频免费观看| 亚洲黄色av女优在线观看| 一个人www欧美| 国产日韩欧美自拍| 欧美电影免费观看高清| 精品精品国产国产自在线| 狠狠色狠狠色综合日日五| 福利一区福利二区微拍刺激| 欧美午夜片在线免费观看| 国产成人亚洲综合青青| 北条麻妃久久精品| 久久久久久中文| 国产一区二区三区在线视频| 伊人久久综合97精品|