欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
把C#中方法重載說(shuō)透

把C#中方法重載說(shuō)透

分類(lèi): C#基礎 4201人閱讀 評論(28) 收藏 舉報

首先我們說(shuō)一下什么是方法重載。在面對對象這樣的高級語(yǔ)言中都允許我們在一個(gè)類(lèi)中定義多個(gè)方法名相同、方法間參數個(gè)數和參數順序不同的方法,對于參數個(gè)數不同或者參數列表不同的情況我們稱(chēng)之為參數列表不同。需要注意的是這里沒(méi)有提到方法的返回值。也就是決定方法是否構成重載有兩個(gè)條件:
(1)在同一個(gè)類(lèi)中;
(2)方法名相同;
(3)參數列表不同。
例如下面的代碼:

  1.     public void Show()//(1)
  2.         {
  3.             Console.WriteLine("Nothing");
  4.         }
  5.         public void Show(int number)//(2)
  6.         {
  7.             Console.WriteLine(number);
  8.         }
  9.         /*
  10.         public int Show(int number)//(3)
  11.         {
  12.             Console.WriteLine(number);
  13.             return number % 5;
  14.         }
  15.         */

 

對于上面的代碼,(1)沒(méi)有參數,(2)使用了一個(gè)int類(lèi)型的參數,(1)和(2)之間就構成了重載。(2)與(3)相比僅僅返回值不同,雖然重載不關(guān)心返回值的不同,但是在C#中不允許存在方法名和參數列表相同、返回值不同的方法,所以(2)和(3)不能同時(shí)存在于代碼中,(3)如果不注釋掉上面的代碼是沒(méi)有辦法通過(guò)編譯的。

上面我們僅僅討論了重載的一些基本常識,下面我們探討一下一些情況稍微復雜的重載情況。

首先我們看第一個(gè)版本:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. namespace OverrideDemo
  5. {
  6.     /// <summary>
  7.     /// 說(shuō)明:本實(shí)例用于講述重載的關(guān)系
  8.     /// 作者:周公
  9.     /// 日期:2008-09-04
  10.     /// 首發(fā)地址:http://blog.csdn.net/zhoufoxcn
  11.     /// </summary>
  12.     class Program
  13.     {
  14.         static void Main(string[] args)
  15.         {
  16.             String s = null;
  17.             Show(s);
  18.             Object o = "123";
  19.             Show(o);
  20.         }
  21.         static void Show(string s)
  22.         {
  23.             Console.WriteLine("String");
  24.         }
  25.         static void Show(Object o)
  26.         {
  27.             Console.WriteLine("Object");
  28.         }
  29.     }
  30. }

大家猜猜這個(gè)程序的運行結果是什么?
以下是程序運行結果:
String
Object

對以上代碼進(jìn)行分析,我們發(fā)現Show()方法有兩種形式,一種是string類(lèi)型的參數,一種是object類(lèi)型參數,在一個(gè)類(lèi)中存在方法名相同、參數列表不同(參數個(gè)數或者參數類(lèi)型不同)的現象我們稱(chēng)之為overloading,即重載。不過(guò)這里的Show()方法的參數比較特殊,因為string類(lèi)繼承于Object類(lèi),也就是Show()方法的參數存在一種繼承關(guān)系。從結果我們可以得出兩點(diǎn)結論:
(1)從String s = null;Show(s);最后調用的是static void Show(string s)這個(gè)方法我們可以得出,C#中方法調用是精確匹配的,也就是s是string類(lèi)型,雖然string類(lèi)型繼承自object類(lèi)型,盡管static void Show(Object o)也滿(mǎn)足條件,但是方法聲明中static void Show(string s)這個(gè)聲明與s類(lèi)型的最接近(因為s是string類(lèi)型,與它最接近),所以執行static void Show(string s),而不執行static void Show(Object o)這個(gè)方法。
(2)從Object o = "123"; Show(o);最后調用的是static void Show(Object o)這個(gè)方法我們可以得出,C#中如果存在方法重載,會(huì )根據其refrence type(引用類(lèi)型)來(lái)調用對象的方法,而不是根據instance type(實(shí)例類(lèi)型)來(lái)調用。盡管”123”是string類(lèi)型,但是它的refrence type是object類(lèi)型的,所以會(huì )調用static void Show(Object o)這個(gè)方法而不是static void Show(string s)。
上面的Main()方法的IL代碼如下:

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // 代碼大小       24 (0x18)
  .maxstack  1
  .locals init ([0] string s,
           [1] object o)
  IL_0000:  nop
  IL_0001:  ldnull
  IL_0002:  stloc.0
  IL_0003:  ldloc.0
  IL_0004:  call       void OverrideDemo.Program::Show(string)
  IL_0009:  nop
  IL_000a:  ldstr      "123"
  IL_000f:  stloc.1
  IL_0010:  ldloc.1
  IL_0011:  call       void OverrideDemo.Program::Show(object)
  IL_0016:  nop
  IL_0017:  ret
} // end of method Program::Main

從上面的IL代碼我們可以看出對于string s=null;這句代碼在IL中表示為:ldnull。

再根據上面的結論,我們看下面的代碼:

  1. using System;
  2. public class Program
  3. {   public static void Main()
  4.     {
  5.     Show(null);
  6.     Show("");
  7.     Show(1);
  8.     }
  9.     static void Show(Object o)
  10.     {
  11.     Console.WriteLine("Object");
  12.     }
  13.     
  14.     static void Show(String s)
  15.     {
  16.     Console.WriteLine("String");
  17.     }
  18.     
  19. }

猜猜上面的代碼執行結果會(huì )是怎樣的?
以下是程序運行結果:
String
String(感謝btbtshu、windman0925提醒此處的筆誤,原來(lái)粘貼錯了,成了Object了,現在已更正)
Object

從上面的運行結果我們可以得出以下結論:
(1)從Show(null)最后調用的是static void Show(String s)方法我們更進(jìn)一步可以說(shuō)在C#中是方法調用盡量精確匹配的。盡管null我們可以理解為一個(gè)空object對象或者一個(gè)空字符串,但是在這里C#還是精確為派生類(lèi)。這就像我們沒(méi)有錢(qián),可以說(shuō)沒(méi)有一分錢(qián)也可以說(shuō)沒(méi)有500英鎊,但是沒(méi)有一分錢(qián)自然就沒(méi)有500億英鎊,所以我們跟別人說(shuō)沒(méi)有錢(qián)的時(shí)候沒(méi)有必要說(shuō)沒(méi)有500億英鎊一樣。在這里自然null就表示空字符串。所以Show(null)這個(gè)方法會(huì )調用static void Show(String s)這個(gè)方法。
這有點(diǎn)像下面的情況:
一次活動(dòng)大會(huì )上,主持人說(shuō):“身高不到1.60m的請坐在1到3排,身高不到1.75m的請做到4到6排,其他的請隨便坐?!?br>上面的語(yǔ)句似乎有些邏輯方面的問(wèn)題,應該說(shuō)身高超過(guò)1.60m但是不到1.75m的請坐到4到6排。但是如果你面對著(zhù)一群拿著(zhù)槍的強盜,他說(shuō)上面的話(huà)時(shí),恰好你也在場(chǎng)并且你的身高是1.55m,你會(huì )坐到哪一排?你總不可能冒著(zhù)挨一槍的危險去糾正他的邏輯錯誤吧?最好的辦法是坐到1到3排。因為無(wú)論怎么說(shuō)你的身高是絕對滿(mǎn)足不到1.60m這個(gè)條件的(盡管你的身高也滿(mǎn)足強盜說(shuō)的第二個(gè)條件,即身高不到1.75米,但是你肯定不會(huì )冒這個(gè)危險,從上下句的意思我們也能推斷出人家的意思就是身高在1.61m到1.74m之間的人坐4到6排)。
在上面的代碼中,你在運行環(huán)境的眼中就是一個(gè)持槍的強盜,雖然null可以理解為null類(lèi)型的string或者null類(lèi)型的object,但是它不能向你問(wèn)清楚這個(gè)到底是null類(lèi)型的string或者null類(lèi)型的object,因為string是Object的派生類(lèi),所以它按照null類(lèi)型的string來(lái)調用相應的方法了。
(2)從Show("")最后調用static void Show(String s)這個(gè)方法進(jìn)一步證明了方法調用是盡量選擇參數最匹配的那個(gè)執行。因為Show("")相當于:string s = ""; Show(s);s的引用類(lèi)型是string,所以會(huì )調用static void Show(String s)這個(gè)方法。
我們在這里可以假設一下:假如存在一個(gè)類(lèi)A是String類(lèi)的派生類(lèi)(實(shí)際上string類(lèi)是sealed的,也就是不可繼承的,所以我說(shuō)了是假設),并且存在在上面的代碼改變如下:

  1. using System;
  2. public class Program
  3. {   public static void Main()
  4.     {
  5.     Show(null);
  6.     Show("");
  7.     }
  8.     static void Show(Object o)
  9.     {
  10.     Console.WriteLine("Object");
  11.     }
  12.     
  13.     static void Show(String s)
  14.     {
  15.     Console.WriteLine("String");
  16.     }
  17.     static void Show(A a)//假設A是String的派生類(lèi),當然實(shí)際上String類(lèi)并沒(méi)有派生類(lèi),這里僅僅是假設
  18.     {
  19.     Console.WriteLine("A");
  20.     }
  21.     
  22. }

如果上面的假設成立,上面的代碼運行結果應該如下:
A
String

(3)為什么Show(1)會(huì )調用static void Show(Object o)這個(gè)方法呢?在這個(gè)類(lèi)中與Show(1)最精確的方法重載應該是static void Show(int i)這種方法聲明,但是方法中沒(méi)有,因為int是繼承自ValueType類(lèi),所以如果沒(méi)有static void Show(int i)這種聲明,那么其次接近的聲明應該是static void Show(ValueType v)這種聲明,可惜方法中依然沒(méi)有,不過(guò)ValueType類(lèi)繼承自Object類(lèi),所以比static void Show(ValueType v)還次一點(diǎn)的方法重載聲明應該是static void Show(Object o),而類(lèi)中也確實(shí)存在這種聲明,所以會(huì )調用static void Show(Object o)這個(gè)方法。當然從int到Object這個(gè)過(guò)程中存在一次box,也就是裝箱(裝箱是從值類(lèi)型到引用類(lèi)型的轉換),這個(gè)可以從下面的IL代碼可以看出來(lái)。

以下是第二種情況下Main()方法的IL代碼:
.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // 代碼大小       32 (0x20)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ldnull
  IL_0002:  call       void OverrideDemo.Program::Show(string)
  IL_0007:  nop
  IL_0008:  ldstr      ""
  IL_000d:  call       void OverrideDemo.Program::Show(string)
  IL_0012:  nop
  IL_0013:  ldc.i4.1
  IL_0014:  box        [mscorlib]System.Int32
  IL_0019:  call       void OverrideDemo.Program::Show(object)
  IL_001e:  nop
  IL_001f:  ret
} // end of method Program::Main

下面我們對第二種情況的代碼做一些變化,代碼如下:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. namespace OverrideDemo
  5. {
  6.     /// <summary>
  7.     /// 說(shuō)明:本實(shí)例用于講述重載的關(guān)系
  8.     /// 作者:周公
  9.     /// 日期:2008-09-04
  10.     /// 首發(fā)地址:http://blog.csdn.net/zhoufoxcn
  11.     /// </summary>
  12.     class Program
  13.     {
  14.         static void Main(string[] args)
  15.         {
  16.             Show(null);
  17.             Show(""); 
  18.             Show(1);
  19.         }
  20.         static void Show(string s)
  21.         {
  22.             Console.WriteLine("String");
  23.         }
  24.         static void Show(Object o)
  25.         {
  26.             Console.WriteLine("Object");
  27.         }
  28.         static void Show(Program p)//Program是當前方法所在的類(lèi)
  29.         {
  30.             Console.WriteLine("Program");
  31.         }
  32.     }
  33. }

 

上面的代碼的運行結果是什么,你能猜出來(lái)嗎?
哈哈,上面的程序代碼是沒(méi)有運行結果的,因為它沒(méi)有辦法編譯!編譯情況如下:
 
為什么不能通過(guò)編譯呢?
原因就出在Show(null)這個(gè)方法這里!如果僅僅有static void Show(string s)和static void Show(Object o)方法構成重載關(guān)系,那么null我們既可以理解為空string引用也可以理解為空Object引用,因為string類(lèi)型的限制更精確一些,所以C#會(huì )按照最精確地匹配成string類(lèi)型,因而會(huì )執行static void Show(string s)這個(gè)方法。這是在前面的代碼中已經(jīng)被證明的??墒乾F在多了一個(gè)static void Show(Program p)方法的重載,null既可以理解成空string類(lèi)型引用,也可以理解成空Program類(lèi)型引用,因為string類(lèi)和Program類(lèi)都是Object類(lèi)的派生類(lèi),所以按照前面的推論自然不會(huì )當成空Object類(lèi)型的引用。因為String類(lèi)和Program類(lèi)之間不存在繼承關(guān)系,按照最精確匹配原則,編譯器無(wú)法決定匹配成String類(lèi)還是Program類(lèi)最精確,所以編譯無(wú)法通過(guò)。

附注:最近嘗試將一些比較基礎的理論的知識用比較淺顯的話(huà)語(yǔ)表達出來(lái),主要是為了方便初學(xué)者理解和學(xué)習,也許某些詞語(yǔ)用得不夠professional,,但是如果詞語(yǔ)太professional了怕初學(xué)者理解起來(lái)有困難,敬請各位大俠諒解,因為本文不是為你們寫(xiě)的。同時(shí)也歡迎各位與我交流經(jīng)驗和心得。最近垃圾郵件太多,所以不便在這里公開(kāi)我的email,如果各位有興趣與我交流,請加我為csdn好友,這樣就能看見(jiàn)我的QQ和email了.

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
淺析C#中的“==”和Equals
ICE—互聯(lián)網(wǎng)通信引擎的學(xué)習筆記 - 空山雪林通用模塊設計工作室 - JavaEye技術(shù)網(wǎng)站
?。。?!C# 字符串詳解?。。。?!
C#反射概念以及實(shí)例詳解 - 51CTO.COM
[干貨來(lái)襲]C#7.0新特性(VS2017可用)(轉)
C#線(xiàn)程單參數的傳遞
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久